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. Check out my not-so-brief Introduction to Manual Pages if you are interested in learning how to reference these manual pages more efficiently and thoroughly. There is a lot more information there beyond the surface-level content.
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 printf
across multiple lines much the same -
printf "\nYour local .vimrc has been stashed in $PWD/config-vim/backup/"\
"\nWARNING: Running this script multiple times will result in"\
" overwriting this backup!"
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