by egfraz
About a year ago I switched from Ubuntu to Arch Linux. After repeating the install process multiple times, I created a shell script to automate most of the steps in the Arch Installation Guide. This script was created on a laptop with a single drive with not existing operating before install.
A couple things to note:
Here are the script contents. It is also available at http://egfrazier.com/arch-bootstrap.sh.
#!/bin/bash
# Command line args
# =================
# Variables
IFACE_NAME=$1
WIFI_DEV_IDX=""
WIFI_NET_NAME=""
WIFI_NET_PASSWORD=""
SYS_DEV_NAME=''
SYS_PART_PREFIX=''
PARTITION_COUNT=0
BOOT_PART_SIZE=0
ROOT_PART_SIZE=0
HOME_PART_SIZE=0
HOSTNAME=''
PART_SCHEME_FILE=''
ROOT_PASSWD=''
LOCALE_REGION=''
LOCALE_ZONE=''
PROMPT="archinit> "
function print {
echo $PROMPT $1
}
# ===============================
# SECTION I: WORKING FROM ARCHISO
# ===============================
# Verify boot mode
# ================
print "Verifying UEFI boot mode"
ls /sys/firmware/efi/efivars &> /dev/null
if [ $? -eq 0 ]; then
print "UEFI boot mode verified"
else
print "/sys/firmware/efi/efivars not found"
print "This system has not been booted in UEFI mode."
print "Please refer to Arch Linux Installation Guide"
print "on how to proceed in BIOS boot mode. Aborting..."
exit
fi
# Connect to the Internet
# =======================
# Check that the wireless interface exists
print "Verifying that $IFACE_NAME interface exists..."
ls /sys/class/net/$IFACE_NAME &> /dev/null
if [ $? -eq 0 ]; then
print "$IFACE_NAME interface exists"
else
print "$IFACE_NAME interface does not exists"
print "Please review your network interface configuratin. Aborting..."
exit
fi
# Ensure rfkill is not blocking wireless
rfkill unblock $WIFI_DEV_IDX
# Start IWD
systemctl start iwd
# Start network connection using IWD
iwctl station $IFACE_NAME scan
iwctl station $IFACE_NAME get-networks
iwctl station $IFACE_NAME connect $WIFI_NET_NAME --passphrase $WIFI_NET_PASSWORD
# Check that the interface is up
IFACE_STATE=$(cat /sys/class/net/$IFACE_NAME/operstate)
IFACE_CARRIER=$(cat /sys/class/net/$IFACE_NAME/carrier)
if [ $IFACE_STATE == "up" ]; then
print "$IFACE_NAME state is UP"
else
print "$IFACE_NAME state is DOWN. Aborting..."
exit
fi
if [ $IFACE_CARRIER -eq 1 ]; then
print "$IFACE_NAME carrier is UP"
else
print "$IFACE_NAME carrier is DOWN. Aborting..."
exit
fi
WIFI_CONNECT_STATUS=$(iwctl station $IFACE_NAME show | grep 'connected' | awk '{print $2}')
if [ $WIFI_CONNECT_STATUS == 'connected' ]; then
print "WiFi connection is UP"
else
print "WiFi connection is DOWN. Aborting..."
exit
fi
# Ping test
ping -c 1 google.com
if [ $? -eq 0 ]; then
print "Ping test successful"
else
print "Ping test unsuccessful. Aborting..."
exit
fi
# Update system clock
timedatectl set-ntp true
# Partition the disks
# Back up existing partition scheme
sfdisk -d /dev/$SYS_DEV_NAME > $SYS_DEV_NAME_part_scheme_preinstall_$(date +'%Y%m%d-%H%M').dump
# Create partition scheme from file
sfdisk -W always -w always /dev/$SYS_DEV_NAME < $PART_SCHEME_FILE
# Format and check the partitions
mkfs.fat -F32 /dev/"$SYS_DEV_NAME$SYS_PART_PREFIX"1
fsck /dev/"$SYS_DEV_NAME$SYS_PART_PREFIX"1
mkfs.ext4 /dev/"$SYS_DEV_NAME$SYS_PART_PREFIX"2
fsck /dev/"$SYS_DEV_NAME$SYS_PART_PREFIX"2
mkfs.ext4 /dev/"$SYS_DEV_NAME$SYS_PART_PREFIX"3
fsck /dev/"$SYS_DEV_NAME$SYS_PART_PREFIX"3
# Mount the partitions
mount /dev/"$SYS_DEV_NAME$SYS_PART_PREFIX"2 /mnt
mkdir -p /mnt/boot
mkdir -p /mnt/home
mount /dev/"$SYS_DEV_NAME$SYS_PART_PREFIX"1 /mnt/boot
mount /dev/"$SYS_DEV_NAME$SYS_PART_PREFIX"3 /mnt/home
# Intall essential packages
pacstrap /mnt base linux linux-firmware efibootmgr iwd git dhcpcd base-devel
# Genrate fstab
genfstab -U /mnt >> /mnt/etc/fstab
# ===============================
# SECTION II: WORKING FROM CHROOT
# ===============================
# Chroot into the new Arch install
# and perform final configurations
cat <<EOF | arch-chroot /mnt
ln -sf /usr/share/zoneinfo/$LOCALE_REGION/$LOCALE_ZONE /etc/localtime
hwclock --systohc
locale-gen
sed -i 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
echo 'LANG=en_US.UTF-8' >> /etc/locale.conf
echo $HOSTNAME > /etc/hostname
echo "127.0.1.1 $HOSTNAME.localdomain $HOSTNAME" > /etc/hosts
echo root:$ROOT_PASSWD | chpasswd
pacman --noconfirm -S grub
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=arch_grub
grub-mkconfig -o /boot/grub/grub.cfg
EOF