Scripts for a new Linux install

I know others may have their own script to install their default set of applications when they install a new distro, (I’m sure I’ve heard Ryan mention this). I have my own script that I’ve tinkered with for a while that has worked on the distros I’ve tried so far, Arch based, Debian based and 2 RPM based.

I run this script after doing any initial software update.

I call it InstallList, but call it what you want and it displays what you call it in the help message.

It can have a built in list of packages (see the variable TO_INSTALL at the top of the script file, and/or it will load a list of packages from a file called defaults.list in the same directory as the script file. The latest bit of over engineering is to accept a file on the command line.

e.g.
$ InstallList extras.list

All packages in any or all of these places will be filtered so any duplicates will be removed from the packages it will try and install. Any packages that are already installed will just end up being skipped by the install command for the base distro type, so no harm.

The script will ask for the base type of the distro (Arch, Debian or RPM) and prompt for the sudo passwork as needed. As I only need to run this once I do the installs one by one, it may take longer but makes the output easier to look back at and see what happened for each package.

Not all distros call application packages the same (chromium or chromium-browser) and sometimes the application I want isn’t in their repo so I add an alternative, which can sometimes lead to both being installed (KeePassXC and KeePassX) but on the whole this doesn’t bother me, if it bothers you adjust the list first or remove the unwanted after the event.

The script uses colours in the messages to try and help readability of the output.

InstallList

#!/bin/bash
#

_BASENAME_="${0##*/}"       # basename of this script file


# ###################################################
#
# 1) as standard, the following list of packages, listed in the varable
#    "_TO_INSTALL_" will be attempted to installed
#
# 2) as well as these, if there is a file called "defaults.list" in the
#    same directory as this script file it will be assumed to be a list
#    of default packages (additional to any listed in "_TO_INSTALL_".
#
# 3) optionally you can specify another file containing yet more
#    packages as a command line argument
#
#    e.g.  InstallList extras.list
#
# NOTE: the script filters out duplicates before attempting to install
#       any packages.
#
# #### embedded list of packages to install as defaults ####
_TO_INSTALL_="
bluefish				build-essential			chromium
chromium-browser		cppcheck				featherpad
geany					geany-plugins			gnome-mahjongg
gnome-system-monitor	gparted					gufw
guvcview				keepassx				keepassxc
kpat					kpatience				ksudoku
leafpad					less					mousepad
neofetch				openshot				orage
pluma					quiterss				rsync
shellcheck				simplescreenrecorder
"


# #### define colour strings for display messages ####
#
_RED_='\e[1;31m'
_GREEN_='\e[1;32m'
_YELLOW_='\e[1;33m'
#_BLUE_='\e[1;34m'
#_MAGENTA_='\e[1;35m'
_CYAN_='\e[1;36m'
_WHITE_='\e[1;37m'
_RESET_='\e[m'


# #### Version String ####
_VERSION_="2019-09-25 v1.25 : (CC0) Creative Commons"

show_version() {

    echo -e "\\n${_YELLOW_}${_BASENAME_} :\\n\\n\\t${_CYAN_}${_VERSION_}${_RESET_}\\n"

}


# #### simple help message string ####
_HELP_="
A simple script to add a selection of default packages to a new Linux distro
installation.

It works on distro based on Arch or Debian, and that use RPM packages.

USAGE :
        ${_YELLOW_}${_BASENAME_} ${_WHITE_}[${_CYAN_}<package.list>${_WHITE_}]${_RESET_}

        ${_CYAN_}<package.list>${_RESET_} - is an optional file containing a list of
                         additional packages"

show_help() {

    echo -e "\\n${_YELLOW_}${_BASENAME_} :\\n\\t${_CYAN_}${_VERSION_}${_RESET_}\\n\\t${_HELP_}\\n"

}


# ###################################################
# if there was an external file of additional
# packages add each line from that file
#
add_extras() {

_TO_INSTALL_="${_TO_INSTALL_}
${1}"

}


# ###################################################
# read any packages from file with additional packages
#
read_list_file() {

    echo -e "\\n${_YELLOW_}**** Reading external package list file ****\\n**** File: ${_CYAN_}${1}${_RESET_}\\n"

    while IFS= read -r line
    do

    if [ "${line}" != "" ]; then add_extras "${line}"; fi  # ignore empty lines

    done < "${1}"

}


# ###################################################
# build a list of unique packages
# start with an empty list of unique packages
#
_UNIQUES_=""

is_unique() {

    for pu in ${_UNIQUES_}
    do
        if [ "${1}" == "${pu}" ]; then return; fi
    done

_UNIQUES_="${_UNIQUES_}
${1}"

}


# ###################################################
# filter out duplicate packages
#
check_unique() {

    echo -e "${_YELLOW_}**** Filtering out duplicate packages ****${_RESET_}"

    for p in ${_TO_INSTALL_}; do is_unique "${p}"; done

}


# ######################################################
# requires 2 arguments :-
#    ${1} = ${_COMMAND_}         - depends on base distro type
#    ${2} = ${_PACKAGE_}         - name of package to install
install_package() {

echo -e "\\n${_CYAN_}\\n**** Installing package '${2}'  BEGIN  ****\\n****${_RESET_}"


_INSTALL_CMD_="sudo ${1} ${2}"
echo -e "${_YELLOW_}${_INSTALL_CMD_}${_RESET_}\\n"

if ! ${_INSTALL_CMD_}; then

    echo -e "${_RED_}****\\n**** Installing package '${2}' FAILED  ****\\n${_RESET_}"

else

    echo -e "${_GREEN_}****\\n**** Installing package '${2}' SUCCESS ****\\n${_RESET_}"

fi

}


##################################################################
#
# start here, see if version info or help was requested ...
#
##################################################################

case "${1}" in

    "-v" | "--version")
        show_version
        exit
        ;;

    "-h" | "--help")
        show_help
        exit
        ;;

    *)
        ;;

esac

##################################################################
#
# version or help NOT requested so ask what distro type you want
# to install,
#
#   a[rch]
#   d[ebian]
#   r[pm]
#
#   or
#
#   q[uit]
#
##################################################################

_DISTRO_TYPE_=""
while [ "${_DISTRO_TYPE_}" == "" ]
do
    read -er -n 1 -p "[A]rch. [D]ebian, [R]PM or q[uit] ? [a/d/r/q] : " -s choice

    case "${choice^^}" in

        "A")
            echo -e "${_YELLOW_}A${_RESET_}rch base selected"
            _DISTRO_TYPE_="pacman -S --noconfirm"
            ;;

        "D")
            echo -e "${_YELLOW_}D${_RESET_}ebian base selected"
            _DISTRO_TYPE_="apt install -yy"
            ;;

        "R")
            echo -e "${_YELLOW_}R${_RESET_}PM base selected"
            _DISTRO_TYPE_="dnf install -yy"
            ;;

        "Q")
            echo -e "\\n${_RED_}**** Quitting ****${_RESET_}\\n"
            exit 1
            ;;

        *)
            echo -e "\\n${_RED_}**** Unknown base distro ****${_RESET_}\\n"
            ;;

    esac
done


# #### read the standard "defaults.list" package list ####
_DEFAULT_LIST_="$( dirname "${0}" )/defaults.list"

if [ -f "${_DEFAULT_LIST_}" ]; then read_list_file "${_DEFAULT_LIST_}"; fi


# #### read any extra package list from command line file ####
if [ "${1}" != "" ]; then read_list_file "${1}"; fi


# #### check for unique package names, discard duplicates ####
check_unique


# #### start processing the list of packages, including any from ####
# #### external file(s) with additional packages                 ####
echo -e "\\n${_YELLOW_}**** '${_BASENAME_}' Starting ****${_RESET_}"
sudo ls >/dev/null


# #### now, process each unique package name and try to install it ####
for p in ${_UNIQUES_}
do

    install_package "${_DISTRO_TYPE_}" "${p}"

done

echo -e "${_YELLOW_}**** '${_BASENAME_}' Finished ****${_RESET_}\\n"

exit

##################################################################

An example of a defaults.list file I could use rather than having the packages in the TO_INSTALL variable would be

defaults.list

bluefish				build-essential			chromium
chromium-browser		cppcheck				featherpad
geany					geany-plugins			gnome-mahjongg
gnome-system-monitor	gparted					gufw
guvcview				keepassx				keepassxc
kpat					kpatience				ksudoku
leafpad					less					mousepad
neofetch				openshot				orage
pluma					quiterss				rsync
shellcheck				simplescreenrecorder

If anyone has suggestions for improvements please let me know, I’m far from being a bash script expert.

7 Likes

Nice one, and I hope I don’t come across negative when I say that my suggestion would be to now implement it in a configuration management system like ansible (or something else, but I don’t really know puppet or chef).

I enjoy implementing a thing myself for the education and sense of accomplishment, but typically in the workplace it’s good to practice using industry standard tools for the economy of your time.

That said, for an environment of 1 machine, the overhead of config management might not be worth it if you’re not doing other tasks like templating configuration files.

Kudos for the use of geany :smiley:

1 Like

I basically keep the master copy of the script on my Google Drive (other scripts also) so I can get at it/them from whatever machine I’m using.

It started as a simple script just for my use with MX or Debian, then I tried Manjaro, ArcoLinux and EndeavourOS so I mashed in so it would work with Arch based distros. I then tried OpenSUSE and Fedora, and crunched in for RPM packages.

And then, I decided it was a mess, so I restructured it and made it more tidy, added colours… tinkering never ends.

I don’t see the need to bother with a config management, the ones I knew when I was “active” are now obsolete and I may someday want a rainy Sunday project and do something like that, I don’t see a great deal of benefit.

I posted it here because a) it may help someone, b) inspire someone to do their own, c) prompt others to share their bash script twiddles.

BTW, I mostly use Pluma, sometimes Featherpad and occasionally Mousepad for scripts. I do use Geany for my attempts to remember C, I used to use K&R C every day back in the 1980s, but not since, and especially not since I retired in 2008.

I like Geany, and it’s project files but I don’t see the need for it for bash scripts, althoughI won’t not use it if it’s what’s to hand.

1 Like

Definitely inspiring, thanks, because I need to get my own scripts in order (and my dotfiles into NextCloud or something so I can synchronise them between environments a bit better).

I also use Geany mostly for C when I do use it, it’s like the Notepad++ of Linux :slight_smile: