Posix Shell Scripting¶
Some neat tricks and methods for scripting.
Directory of the Script¶
At the start of my scripts is always the same line:
Looks odd? Well, let's explain it and then you'll be enlightened. This is very portable
CDPATH=
Unset the CDPATH
environment variable to make sure we don't search outside of where we tell cd to go. If you man cd
you'll possibly find that CDPATH
is an environment variable that can be used like as a search list, much like the PATH
environment variable. We don't want surprises.
cd --
Change directory. The double heiphen marks the end of options input to the cd
command so that directories with odd names that start with a heiphen and will be mistaken for options instead of the directory name don't cause problems.
$()
Use a subshell - substitutes the output of the command run in the subshell
dirname -- "$0"
Output the directory name of the command line used to execute the shell script (which is in "${0}"
).
&& pwd
Once the current working directory has been changed to the script's directory we run the pwd
tool to get the absolute path of the program's working directory.
Input Arguments¶
There are many ways to process input arguments for scripts. You can check out the man page for the getopts command.
I prefer the while loop approach however
While Loop Arguments¶
while [ $# -gt 0 ]; do
case "${1}" in
--clean)
echo "CLEANING"
;;
--verbose|-v)
echo "VERBOSE"
;;
--file|-f)
shift
echo "FILE: ${1}"
;;
esac
shift
done
Some examples of this in use:
Looping¶
Various ways of looping depending on the data set.
Multiple Line Variables¶
Sometimes we end up with a multiline list in a variable and we want to do something for each item in the list. Looping over this list portably is straight forward using a HEREDOC
directed into a while loop:
files=$(ls -1 /etc)
while read -r file; do
echo "Do something with ${file}"
done << EOF
${files}
EOF
Output:
Do something with abrt
Do something with adjtime
Do something with aliases
Do something with alsa
Do something with alternatives
Do something with anaconda
...
Space Separated Variables¶
Looping over a space-separated list is a bit easier and can be done in a for loop. Can't have any spaces in the list items though.
packages="gcc gcc-g++ gdb autotools automake"
for package in ${packages}; do
echo "Do something with ${package}"
done
Output:
Do something with gcc
Do something with gcc-g++
Do something with gdb
Do something with autotools
Do something with automake
Heredocs¶
These extremely useful things can be used in many places. Some examples of how they can be used below. I end up using them for writing configuration files often.
Write File from Heredoc¶
Variables are substituted normally when using a heredoc with variables inside it:
Output
[brian@brian-2920x ~]$ cat config.yaml
language: en-GB
If you single quote the heredoc variables are not substituted:
```bash
language=en-GB
cat << 'EOF' > config.yaml
language: ${language}
EOF
Output