Skip to main content

Examples

Read the manual page for bash!
Yes, all of it - within reason. Even if you don't fully understand the material in front of you, it is good to give it a once-over just so you are aware it exists. I can't count how many times I've returned to the Bash manual page to re-read something I previously didn't understand, but had just suddenly clicked while working on some side project.

Just read the page, and know it exists. CheckIt is always readily available to you and quick to search through. If needed, check out my not-so-brief Introduction to Manual Pages ifto you are interested in learninglearn how to reference these manual pages more efficientlyefficiently.

and

Creating thoroughly. There is a lot more information there beyond the surface-level content.

Scripts

Bash scripting is much like interacting with the bash terminal - the similarity can be easily seen in how we would split a bash command to multiple lines...

kapak@base:~$ l\
> s -la
total 76
drwxr-xr-x 9 kapak kapak  4096 Jul 28 01:24 .
drwxr-xr-x 3 root  root   4096 Jul  6 09:49 ..
-rw------- 1 kapak kapak  5423 Jul 20 18:10 .bash_history
-rw-r--r-- 1 kapak kapak   220 Jul  6 09:49 .bash_logout
-rw-r--r-- 1 kapak kapak  3771 Jul  6 09:49 .bashrc
...( Reduced Output ) ...
kapak@base:~$ ls -la
total 76
drwxr-xr-x 9 kapak kapak  4096 Jul 28 01:24 .
drwxr-xr-x 3 root  root   4096 Jul  6 09:49 ..
-rw------- 1 kapak kapak  5423 Jul 20 18:10 .bash_history
-rw-r--r-- 1 kapak kapak   220 Jul  6 09:49 .bash_logout
-rw-r--r-- 1 kapak kapak  3771 Jul  6 09:49 .bashrc
...( Reduced Output ) ...

In a bash script, we would handle splitting printfls -la across multiple lines much the samesame. Create the file below, name it test.sh - 

printf#/bin/bash
"\nYourls local-la
.vimrcl\
hass been-la
stashed
in

Now $PWD/config-vim/backup/"\make "\nWARNING:the Runningfile executable and run the script, you should see the output of ls -la twice, since this script multipleis timesa willsimple resultexample in"\of "splitting overwritingcommands thisacross backup!"lines.

# Make the script executable
sudo chmod a+x test.sh 
# Run the script
./test.sh
Printf Formatting

This is just one of many commands in bash, but you will use it a lot so getting to know the syntax well will make your life a lot easier. Read the below script carefully, and you will have a basic understanding of how printf can be used dynamically within scripts to provide consistent formatting.

    #/bin/bash
    divider===============================
    divider=$divider$divider

    header="\n %-10s %8s %10s %11s\n"
    format=" %-10s %08d %10s %11.2f\n"

    width=43

    printf "$header" "ITEM NAME" "ITEM ID" "COLOR" "PRICE"

    printf "%$width.${width}s\n" "$divider"

    printf "$format" \
    Triangle 13  red 20 \
    Oval 204449 "dark blue" 65.656 \
    Square 3145 orange .7

    # https://linuxconfig.org/bash-printf-syntax-basics-with-examples
 
Examples

Check out my snippet repository for more up-to-date scripts, configurations - /shaunrd0/klips
Basic script example, found with the Pi book on Knoats - Staging Configs to a USB

#!/bin/bash
##Unstash.sh script using stashed settings for custom MM
##Unpacks stashed settings copied by stash.sh
##Used to prevent loss of working configs if unstash.sh fails
##To return to last working state,format the pi and run unpack.sh
##Use repack.sh and unpack.sh to backup working builds
###############################################################################

printf "\nDo you want to setup stashed PI settings?\n"
read Pi

if [ $Pi == 'Y' ]||[ $Pi == 'y' ]
then
        sudo cp -vu $DIR/wpa_supplicant.conf /etc/wpa_supplicant/
        sudo cp -vu $DIR/ssh_config /etc/ssh/
        sudo cp -vu $DIR/sshd_config /etc/ssh/
        sudo cp -vur $DIR/.ssh/ $HOME
        sudo systemctl restart ssh.service sshd.service
        #sshd fails to restart on Debian / PI?
fi

printf "\nDo you want to install MagicMirror?\n"
read Script

if [ $Script == 'y' ] || [ $Script == 'Y' ]
then
        printf "\nInstalling Magic Mirror using custom unstash script....\n\n"

        printf "\ncurl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -\n"
        curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -

        printf "\nsudo apt install -y nodejs\n"
        sudo apt install -y nodejs

        printf "\nsudo npm install pm2 -g\n"
        sudo npm install pm2 -g

        printf "\nsudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u $USER --hp /home/pi\n"
        sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u $USER --hp $HOME

        printf "\nsudo git clone https://github.com/michmich/magicmirror\n"
        sudo git clone https://github.com/MichMich/MagicMirror

        printf "\nnpm install\n"
        cd $HOME/MagicMirror && sudo npm install
        cd

        printf "unstash.sh magic mirror install complete.\nMagic Mirror installed! Navigate to ~/magicmirror/ and run the following to start manually:\nnpm start\n\n"
fi

printf "\nCopy stashed Magic Mirror configs?\n"
read Configs

if [ "$Configs" == "y" ] || ["$Configs" == "Y" ]
then
        # I can't remember why I didnt specify a root for stash/ here
        # Stick $DIR here if needed, I think it is
        sudo cp -ruv  /stash/MagicMirror/* $HOME/magicmirror/
        sudo cp -vu /mm.sh $HOME
        sudo chmod a+x mm.sh
fi

#Regardless of path, show useful help text, script finished
pm2 startup
printf "\n###########Important Instructions###########\nBe sure to also run the following to save pm2 status:\npm2 save\nTo see pm2 command examples, run -h or pm2 examples:\npm2 -h\npm2 examples\n\nRUN COMMAND BELOW TO START MAGIC MIRROR:\n\npm2 start mm.sh\n"

Do something in a subshell (a background shell) -

$ (cd /var/log && cp -- *.log ~/Desktop)

While loop using conditionals within bash to automate cmake builds -

#!/bin/bash
## Author: Shaun Reed | Contact: shaunrd0@gmail.com | URL: www.shaunreed.com ##
## A custom bash script for building cmake projects.                         ##
## Intended to be ran in root directory of the project alongside CMakeLists  ##
###############################################################################

# Infinite while loop - break on conditions
while true
do

  printf "\nEnter 1 to build, 2 to cleanup previous build, 0 to exit.\n"
  read bChoice

  # Build loop
  # If input read is == 1
  if [ $bChoice -eq 1 ]
  then
    mkdir build
    # Move to a different directory within a subshell and build the project
    # The '(' and ')' here preserves our working directory
    (cd build && cmake .. && cmake --build .)
  fi

  # Clean-up loop
  # If input read is == 2
  if [ $bChoice -eq 2 ]
  then
    printf "test\n"
    rm -Rv build/*
  fi

  # Exit loops, all other input - 

  # If input read is >= 3, exit
  if [ $bChoice -ge 3 ]
  then
    break 
  fi

  # If input read is <= 0, exit
  if [ $bChoice -le 0 ]
  then
    break
  fi

  # Bash will print an error if symbol or character input

done​