#!/usr/bin/env bash # This script will ask users about their prefrences # like disk, file system, timezone, keyboard layout, # user name, password, etc. # shellcheck disable=SC2207 SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" # set up a config file CONFIG_FILE=$SCRIPT_DIR/setup.conf # check if file exists if [ ! -f "$CONFIG_FILE" ]; then # create file if not exists touch -f "$CONFIG_FILE" fi # set options in setup.conf set_option() { # check if option exists if grep -Eq "^${1}.*" "$CONFIG_FILE"; then # delete option if exists sed -i -e "/^${1}.*/d" "$CONFIG_FILE" fi # else add option echo "${1}=${2}" >> "$CONFIG_FILE" } # Adding global functions and variables to use in this script # check for root user check_root() { if [[ "$(id -u)" != "0" ]]; then echo -ne "ERROR! This script has to be run under the 'root' user!" exit 1 fi } # check if distro is arch check_arch() { if [[ ! -e /etc/arch-release ]]; then echo -ne "ERROR! This script has to be run under Arch Linux!" exit 1 fi } # check for internet connection connection_test() { ping -q -w 1 -c 1 "$(ip r | grep default | awk 'NR==1 {print $3}')" &>/dev/null && return 1 || return 0 } # Backround checks background () { if connection_test; then echo -ne "ERROR! There seems to be no internet connection.\n" exit 1 else check_root check_arch fi } elements_present() { # check if an element exists for e in "${@:2}"; do [[ "$e" == "$1" ]] && break; done } invalid_option() { # invalid option message echo -ne "Please select a valid option: \n" } set_password() { # password helper function # read password without echoing (-s) read -rs -p "Please enter password: " PASSWORD1 echo -ne "\n" read -rs -p "Please re-enter password: " PASSWORD2 echo -ne "\n" if [ "$PASSWORD1" == "$PASSWORD2" ]; then set_option "$1" "$PASSWORD1" else echo -ne "Passwords do not match \n" return fi } # make a title title () { echo -ne "\n" echo -ne "------------------------------------------------------------------------\n" echo -ne "\t\t\t$1\n" echo -ne "------------------------------------------------------------------------\n" } # ask user for option PROMPT="Please enter your option: " logo () { # This will be shown on every set as user is progressing echo -ne " ------------------------------------------------------------------------- █████╗ ██████╗ ██████╗██╗ ██╗████████╗██╗████████╗██╗ ██╗███████╗ ██╔══██╗██╔══██╗██╔════╝██║ ██║╚══██╔══╝██║╚══██╔══╝██║ ██║██╔════╝ ███████║██████╔╝██║ ███████║ ██║ ██║ ██║ ██║ ██║███████╗ ██╔══██║██╔══██╗██║ ██╔══██║ ██║ ██║ ██║ ██║ ██║╚════██║ ██║ ██║██║ ██║╚██████╗██║ ██║ ██║ ██║ ██║ ╚██████╔╝███████║ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ " } setpartionlayout() { # Set partioning layouts title "Setup Partioning Layout" LAYOUTS=("Default" "LVM" "LVM+LUKS" "Maintain Current") PS3="$PROMPT" select OPT in "${LAYOUTS[@]}"; do if elements_present "$OPT" "${LAYOUTS[@]}"; then case "$REPLY" in 1) set_option "LAYOUT" 1 break ;; 2) set_option "LAYOUT" "$OPT" set_option "LVM" 1 set_option "LUKS" 0 break ;; 3) set_option "LAYOUT" "$OPT" set_password "LUKS_PASSWORD" set_option "LUKS" 1 set_option "LVM" 1 break ;; 4) echo -ne "Maintaining current settings" set_option "LAYOUT" 0 break ;; *) invalid_option setpartionlayout ;; esac else invalid_option filesystem fi done } filesystem () { # This function will handle file systems. At this movement we are handling only # btrfs and ext4. Others will be added in future. title "Setup File System" FILESYS=("btrfs" "ext2" "ext3" "ext4" "f2fs" "jfs" "nilfs2" "ntfs" "reiserfs" "vfat" "xfs") PS3="$PROMPT" select OPT in "${FILESYS[@]}"; do if elements_present "$OPT" "${FILESYS[@]}"; then if [ "$OPT" == "btrfs" ]; then # used -a to get more than one argument echo -ne "Please enter your btrfs subvolumes separated by space\n" echo -ne "usualy they start with @ for root or @home, @temp etc.\n" echo -ne "Defaults are @, @home, @var, @tmp, @.snapshots \n" read -r -p "press enter to use default: " -a ARR if [[ -z "${ARR[*]}" ]]; then set_option "SUBVOLUMES" "(@ @home @var @tmp @.snapshots)" break else # An array is a list of values. NAMES=() for i in "${ARR[@]}"; do # push values to array NAMES+=("$i") done # set to config file set_option "SUBVOLUMES" "(${NAMES[*]})" break fi fi set_option "FS" "$OPT" break else invalid_option break fi done } timezone () { # Added this from arch wiki https://wiki.archlinux.org/title/System_time title "Setup Time Zone" _TIMEZONE="$(curl --fail https://ipapi.co/timezone)" _ZONE=($(timedatectl list-timezones | sed 's/\/.*$//' | uniq)) echo -ne "System detected your timezone to be '$_TIMEZONE'" echo -ne "\n" read -r -p "Is this correct? yes/no: " ANSWER case "$ANSWER" in y|Y|yes|Yes|YES) set_option TIMEZONE "$_TIMEZONE" ;; n|N|no|NO|No) title "Manually setting timezone" PS3="$PROMPT" echo -ne "Please select your zone: \n" select ZONE in "${_ZONE[@]}"; do if elements_present "$ZONE" "${_ZONE[@]}"; then _SUBZONE=($(timedatectl list-timezones | grep "${ZONE}" | sed 's/^.*\///')) PS3="$PROMPT" echo -ne "Please select your subzone: \n" select SUBZONE in "${_SUBZONE[@]}"; do if elements_present "$SUBZONE" "${_SUBZONE[@]}"; then set_option "TIMEZONE" "${ZONE}/${SUBZONE}" break else invalid_option break fi done break else invalid_option break fi done ;; *) echo "Wrong option. Try again";timezone;; esac } keymap () { # These are default key maps as presented in official arch repo archinstall title "Setup Keymap" KEYMAPS=("by" "ca" "cf" "cz" "de" "dk" "es" "et" "fa" "fi" "fr" "gr" "hu" "il" "it" "lt" "lv" "mk" "nl" "no" "pl" "ro" "ru" "sg" "ua" "uk" "us") PS3="$PROMPT" select OPT in "${KEYMAPS[@]}"; do if elements_present "$OPT" "${KEYMAPS[@]}"; then set_option "KEYMAP" "$OPT" break else invalid_option keymap fi done } drivessd () { # confirm if ssd is present title "SSD Drive Confirmation" read -r -p "Is this system using an SSD? yes/no: " _SSD case "$_SSD" in y|Y|yes|Yes|YES) set_option "SSD" 1 set_option "MOUNTOPTION" "noatime,compress=zstd,ssd,commit=120" ;; n|N|no|NO|No) set_option "SSD" 0 set_option "MOUNTOPTION" "noatime,compress=zstd,commit=120" ;; *) echo "Wrong option. Try again";drivessd;; esac } diskSELECTION () { # Selection for disk type # show disks present on system title "Disk Selection" DISKLIST="$(lsblk -n --output TYPE,KNAME,SIZE | awk '$1=="disk"{print "/dev/"$2" - "$3}')" # show disks with /dev/ prefix and size PS3="$PROMPT" select _DISK in "${DISKLIST[@]}"; do if elements_present "$_DISK" "${DISKLIST[@]}"; then # remove size from string DISK=$(echo "$_DISK" | awk '{print $1}') set_option "DISK" "$DISK" break else invalid_option break fi done } userinfo () { title "Add Your Information" read -r -p "Please enter your username: " USERNAME set_option "USERNAME" "${USERNAME,,}" # convert to lower case as in issue #109 set_password "PASSWORD" read -r -p "Please enter your hostname: " HOSTNAME set_option "HOSTNAME" "$HOSTNAME" } setlocale (){ # set locale title "Setup Locale" LOCALES=($(grep UTF-8 /etc/locale.gen | sed 's/\..*$//' | sed '/@/d' | awk '{print $1}' | uniq | sed 's/#//g')) PS3="$PROMPT" select LOCALE in "${LOCALES[@]}"; do if elements_present "$LOCALE" "${LOCALES[@]}"; then set_option "LOCALE" "${LOCALE}.UTF-8 UTF-8" break else invalid_option break fi done } setdisktop() { title "Select either Disktop Environment or Window Manager" SELECTION=("KDE" "Gnome" "XFCE" "Mate" "LXQT" "Minimal" "Awesome" "OpenBox" "i3" "i3-Gaps") PS3="$PROMPT" select OPT in "${SELECTION[@]}"; do if elements_present "$OPT" "${SELECTION[@]}"; then case "$REPLY" in 1) # more packages can be added here set_option "DE" "('plasma')" set_option "DM" "sddm" break ;; 2) set_option "DE" "('gnome')" set_option "DM" "gdm" break ;; 3) set_option "DE" "('xfce4')" set_option "DM" "lightdm" break ;; 4) set_option "DE" "('mate')" set_option "DM" "lightdm" break ;; 5) set_option "DE" "('lxqt')" set_option "DM" "lightdm" break ;; 6) set_option "DE" 0 set_option "DM" 0 break ;; 7) set_option "DE" 0 set_option "WM" "awesome" break ;; 8) # openbox set_option "DE" 0 set_option "WM" "openbox" break ;; 9) # i3 set_option "DE" 0 set_option "WM" "i3" break ;; 10) # i3-gaps set_option "DE" 0 set_option "WM" "i3-gaps" break ;; *) echo "Wrong option. Try again" break ;; esac else invalid_option break fi done } makechoice () { # make choice for installation title "Make your choice" CHOICE=("Default Install" "Custom Install") PS3="$PROMPT" select OPT in "${CHOICE[@]}"; do if elements_present "$OPT" "${CHOICE[@]}"; then case "$REPLY" in 1) logo break ;; 2) userinfo break ;; *) echo "Wrong option. Try again" break ;; esac else invalid_option break fi done } background logo makechoice # setdisktop # check_root # Starting functions # clear # logo # title "Please select presetup \n\t\t\tsettings for your system" # userinfo # setpartionlayout # filesystem # clear # logo # diskselection # drivessd # clear # logo # timezone # clear # logo # keymap # clear # logo # setlocale