Last active
April 18, 2023 20:11
-
-
Save JoshuaJChan/aaf4de5fb7d6c82209fe0314602c4679 to your computer and use it in GitHub Desktop.
script to install Arch Linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
## Assumes ## | |
# Working internet connection | |
# Pre-installation work already done | |
## Instructions ## | |
# After booting into Arch ISO, run: | |
# curl -sL https://git.io/JexlX | /bin/bash | |
# and follow the instructions on the script. | |
# You can always Ctrl-C to interrupt the script. | |
## Safer Bash Scripting ### | |
set -euo pipefail #e: exits immediatly if failure, u:exit if using unset variables, o pipefail: if using pipeline, will exit where it failed since if not set, it would have still gone on to the last command even if prev command failed, | |
#set -x #shows the actually bash command before executing it(verbose) | |
trap 's=$?; echo "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR #trap catches signals and execute code when they appear, on error, the echo command is called and ERR is the type error that trap catches | |
### Set up logging ### | |
exec 1> >(tee "stdout.log") | |
exec 2> >(tee "stderr.log") | |
### Start of Installer ### | |
printf "Welcome to my awesome Arch Installer. This script assumes a network is already configured.\n\n 0 - default partion scheme using ext4 fs(needs atleast 40.5 GB of storage): 260MiB /boot, 30GB root, 10GB swap, remaining space home;\n 1 - custom installation\n\nNOTE: If you have UEFI, systemd-boot will be installed. If you have BIOS, GRUB will be installed. Please modify the script to change the bootloader.\n\nHow would you like to install Arch? [0/1] " | |
read method < /dev/tty #must specific input from current tty otherwise will take stdin from other sources such as pipes | |
## default ## | |
if [ ${method:-0} -eq 0 ]; then | |
devicelist=$(lsblk -dplnx size -o name,size | grep -Ev "boot|rpmb|loop" | tac) #list devices of only their name and size, excluding non disks, tac prints in rev order | |
device=$(dialog --stdout --menu "Select disk to install to" 0 0 0 ${devicelist}) || exit 1 #redirect output to stdout to variable, if unsuccessful command exit 1 | |
hostname=$(dialog --stdout --inputbox "Enter hostname" 0 0) || exit 1; #if LHS unsuccess, will exit with error 1, must put semicolon to clear properly, also needs backslash for properly reading inner variables | |
clear; # don't forget semicolon | |
: ${hostname:?"hostname cannot be empty"} | |
password=$(dialog --stdout --passwordbox "Enter admin password" 0 0) || exit 1; #setting root password | |
clear; | |
: ${password:?"password cannot be empty"} | |
password2=$(dialog --stdout --passwordbox "Enter admin password again" 0 0) || exit 1; | |
clear; | |
[[ "$password" == "$password2" ]] || ( echo "Passwords did not match"; exit 1; ) | |
timedatectl set-ntp true | |
#echo "Would you like to modify the keyboard layout? (y/n)" #***needs to be fixed | |
#read method2 < /dev/tty | |
#if [ "$method2" == "y" ] || [ "$method2" == "Y" ]; then | |
#localectl list-keymaps # list possible layouts | |
#localectl status # current layout | |
#echo "Scroll back the see the options. The current keyboard settings are shown above" | |
#echo "Please enter a choice from the list of keymaps" | |
#read keymap < /dev/tty | |
#loadkeys $keymap # switch the layout to us | |
#: ${keymap:?"Can not be empty"} | |
#fi | |
if [ -d /sys/firmware/efi/efivars/ ]; then #for uefi | |
echo "Creating UEFI boot"; | |
cpu=$(dialog --stdout --menu "Select your CPU type" 0 0 0 Intel "" AMD "") || exit 1 | |
if [ cpu == Intel ]; then | |
cpu=intel; | |
else | |
cpu=amd; | |
fi | |
#no user intervention, use chosen device, end of command options, make gpt type | |
#efi boot partition **MUST BE fat32 WHEN USING GNU PARTED** recommended size of 260MiB | |
#flag the partition that contains the /boot directory as bootable | |
#root partition taking 30G | |
#swap partition matching the 10GB of ram | |
#home partition taking rest of space | |
#***IMPORTANT*** can not have spaces after backslash! or else will not run properly | |
parted --script "${device}" -- mklabel gpt \ | |
mkpart ESP fat32 1MiB 261MiB \ | |
set 1 esp on \ | |
mkpart primary ext4 261MiB 30.5GiB \ | |
mkpart primary linux-swap 30.5GiB 40.5GiB \ | |
mkpart primary ext4 40.5GiB 100%; | |
else #for bios | |
echo "Creating BIOS boot"; # must do "bios_grub" as flag for the set command in parted; more info: https://www.gnu.org/software/parted/manual/html_node/set.html | |
parted --script "${device}" -- mklabel gpt \ | |
mkpart primary ext4 1MiB 261MiB \ | |
set 1 bios_grub on \ | |
mkpart primary ext4 261MiB 30.5GiB \ | |
mkpart primary linux-swap 30.5GiB 40.5GiB \ | |
mkpart primary ext4 40.5GiB 100%; | |
fi | |
# device paths for each part created from parted | |
bootPath="$(ls ${device}* | grep -E "^${device}p?1$")" | |
rootPath="$(ls ${device}* | grep -E "^${device}p?2$")" | |
swapPath="$(ls ${device}* | grep -E "^${device}p?3$")" | |
homePath="$(ls ${device}* | grep -E "^${device}p?4$")" | |
wipefs "${bootPath}" | |
wipefs "${rootPath}" | |
wipefs "${swapPath}" | |
wipefs "${homePath}" | |
# format each path | |
if [ -d /sys/firmware/efi/efivars/ ]; then #if efi boot, need to change format of boot partition | |
mkfs.vfat -F32 "${bootPath}" | |
else | |
mkfs.ext4 "${bootPath}" | |
fi | |
mkfs.ext4 "${rootPath}" #root, swap and home in that order | |
mkswap "${swapPath}" | |
mkfs.ext4 "${homePath}" | |
swapon "${swapPath}" | |
mount "${rootPath}" /mnt #directory already exists ***IMPORTANT: Must mount other partitions AFTER /mnt otherwise, the other dirs will be hidden by the new /mnt filesystem | |
mkdir /mnt/boot; #IMPORTANT: DO NOT make /mnt/efi since systemd-boot by default searches and updates for configurations from /mnt/boot | |
mount "${bootPath}" /mnt/boot | |
mkdir /mnt/home | |
mount "${homePath}" /mnt/home | |
pacstrap /mnt base linux linux-firmware efibootmgr dosfstools os-prober mtools linux-headers vim base-devel redshift firefox network-manager-applet bluez-utils xorg-server xorg-xinit xf86-video-intel xorg-input-libinput paccache htop tlp; | |
genfstab -U /mnt >> /mnt/etc/fstab | |
#cool side note: if you put the - after the <<, the indents will be taken into account before lines in the heredoc; it's not used here tho | |
arch-chroot /mnt /bin/bash <<- EOF | |
ln -sf /mnt/usr/share/zoneinfo/Canada/Eastern /etc/localtime | |
hwclock --systohc | |
sed -e 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/g' -i /etc/locale.gen | |
locale-gen | |
echo "LANG=en_US.UTF-8" > /etc/locale.conf | |
# echo "KEYMAP=us" > /etc/vconsole.conf #changing the keyboard layout | |
echo "${hostname}" > /etc/hostname | |
cat << EOF1 > /etc/hosts | |
127.0.0.1 localhost | |
::1 localhost | |
127.0.1.1 ${hostname}.localdomain ${hostname} | |
EOF1 | |
# mkinitcpio -P #only if have encrypt fs, raid, or lvm | |
EOF | |
#***IMPORTANT: for systemd-boot, must have add initrd intel-ucode.img as FIRST initrd (assuming I have an intel CPU, otherwise put amd) | |
# must install intel-ucode pkg (or amd-ucode pkg) | |
# on the contrary, GRUB automatically detects the cpu type so oh well... | |
if [ -d /sys/firmware/efi/efivars/ ]; then #install systemd-boot bootloader | |
arch-chroot /mnt bootctl install | |
cat <<EOF > /mnt/boot/loader/loader.conf | |
default arch | |
EOF | |
pacstrap /mnt $cpu-ucode linux # must do bootctl install THEN pacstrap/install $cpu-ucode. Why? So that the img files are found in the same directory! /boot directory, and im not sure why but you have to reinstall linux so that the other .img files will appear in /boot... I will have to re organize this later... | |
cat << EOF2 > /mnt/boot/loader/entries/arch.conf | |
title Arch Linux | |
linux /vmlinuz-linux | |
initrd /$cpu-ucode.img | |
initrd /initramfs-linux.img | |
options root=PARTUUID=$(blkid -s PARTUUID -o value "$rootPath") rw | |
EOF2 | |
else #install grub bootloader | |
pacstrap /mnt grub | |
arch-chroot /mnt grub-install --target=i386-pc ${device} | |
#arch-chroot /mnt grub-install --target=x86_64-efi --bootloader-id=grub_uefi --efi-directory=/boot --recheck; # for uefi | |
arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg | |
fi | |
echo "root:$password" | arch-chroot /mnt chpasswd #chpasswd takes the format of changing passwords by (name):(new password) | |
elif [ $method -eq 1 ]; then | |
cgdisk; | |
hostname=$(dialog --stdout --inputbox "Enter hostname" 0 0) || exit 1; #if LHS unsuccess, will exit with error 1, must put semicolon to clear properly, also needs backslash for properly reading inner variables | |
clear; # don't forget semicolon | |
: ${hostname:?"hostname cannot be empty"} | |
password=$(dialog --stdout --passwordbox "Enter admin password" 0 0) || exit 1; #setting root password | |
clear; | |
: ${password:?"password cannot be empty"} | |
password2=$(dialog --stdout --passwordbox "Enter admin password again" 0 0) || exit 1; | |
clear; | |
[[ "$password" == "$password2" ]] || ( echo "Passwords did not match"; exit 1; ) | |
timedatectl set-ntp true | |
fi | |
echo "--- Finished ---" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment