.. title: Shell Scripting Cookbook .. slug: shell-scripting-cookbook .. date: 2016-11-10 19:36:14 UTC .. updated: 2016-11-10 19:36:14 UTC .. tags: shell .. category: .. link: .. description: .. type: text Tips I have learned on how to do things in shell scripts. .. TEASER_END: Read more Quit or Exit the Script if a Failure Occurs ------------------------------------------- Set the shell's *e* option. :: #!/bin/sh set -e true false Alternative way to set the *e* option. :: #!/bin/sh -e true false To disable the option use ``+``. :: #!/bin/sh set -e true set +e false Print Command Before Executing ------------------------------ Set the shell's *x* option. :: #!/bin/sh set -x true false Alternative way to set the *e* option. :: #!/bin/sh -x true false There's a difference between *x* and *v*. In *v* a variable is printed as a variable and in *x* the variable's value is printed. :: #!/bin/sh a='Hello World!' set -v printf "${a}" set +v set -x printf "${a}" set +x To disable the option use ``+`` as shown in the above example. Compare Version Numbers ----------------------- Comparing two version numbers in dot separated format (e.g. 1.2.3) can be done in two ways. Using BSD or GNU ``sort`` to find older version. :: #!/bin/sh a=1.2.0 b=1.2.1 printf "${a}\n${b}\n" | sort -t. -k 1,1n -k 2,2n -k 3,3n | head -n1 Using BSD or GNU ``sort`` to find newer version. :: #!/bin/sh a=1.2.0 b=1.2.1 printf "${a}\n${b}\n" | sort -t. -k 1,1nr -k 2,2nr -k 3,3nr | head -n1 Using GNU ``sort`` to find older version. :: #!/bin/sh a=1.2.0 b=1.2.1 printf "${a}\n${b}\n" | sort -V | head -n1 Using GNU ``sort`` to find newer version. :: #!/bin/sh a=1.2.0 b=1.2.1 printf "${a}\n${b}\n" | sort -Vr | head -n1 Assert ------ The ``test`` command is a rough equivalent to assert in other languages. Read its man page (``man test``) for more information. Recover from Error Return Code ------------------------------ For commands that can return a non-zero exit code and possibly stop the script, use OR (``||``) operator with an alternative command that is sure to succeed. The ``true`` boolean value is one such command. :: #!/bin/sh -e git clone https://example.com/example.git /path/already/exists || true Another example is to create and checkout a git branch that already exists. :: #!/bin/sh -e git checkout -b mybranch origin/mybranch || git checkout mybranch The shell builtin ``:`` (used without arguments here) returns a zero exit code. In this case ``true`` and ``:`` are functionally equivalent. :: #!/bin/sh -e git clone https://example.com/example.git /path/already/exists || : Source a File ------------- To source a file means to execute it as if it was entered by a user manually. It is not run in a separate shell. So e.g. any ``export``-ed variables become available in the current script as environment variables. In Bourne shell (``/bin/sh``) command ``.`` is used to source a file. Command ``source`` does not work in ``/bin/sh``. :: #!/bin/sh . file_to_source.sh