Linux Admin Basics 2 of 3 – shell scripting

Bash Options

You can set bash option in two ways, with shopt or with set command. For example:

shopt -s extglob
set -o nounset

Here is a list of options. I often use “set -e” right after shebang to tell the script to exit upon failed command, because the rest of the script will be error-prone after the failed command. I can use “set +e” to negate the flag.

Also, we can use the unset command to delete the variables during program execution, or the export command to export a variable or function to the environment of all the child processes running in the current shell.

User menu and argument processing

It is a common task in bash scripting to display user menu or process argument. Both use case structure. Here are the examples:

User menu:

#! /bin/bash
select car in BMW TOYOTA TESLA
   case $car in
      echo "X3";;
      echo "Camry";;
      echo "Some";;
      echo "Unknown";;

Argument processiong example:

#! /usr/bin/bash
while getopts ":ht" opt; do
  case ${opt} in
    h ) echo "option h"
    t ) echo "option t"
    \? ) echo "Usage: cmd [-h] [-t]"

Try to run the script with the following options:

$ -t
$ -h
$ -ht
$ -th
$ -a

Build-in commands declare, local, let, eval

The declare command allow you to assign an attribute to a variable. For example:

  • -a indexed array
  • -A associative array
  • -i integer
  • -r read only

The local descriptor declare a variable that is only effective in the code block. For example, within the function.

With command let, each arg is taken as arithmetic expression:

$ A=1
$ B=2
$ let sum=$A+$B
$ echo "A=$A, B=$B, C=$C"
$ A=1, B=2, C=3

With command eval, each arg is taken as a string:

$ A=1
$ B=2
$ eval sum=$A+$B
$ echo "A=$A, B=$B, C=$C"
A=1, B=2, C=1+2

Commands trap and inotifywait

The trap command that you can use to catch signals from script and execute code. For example:

trap "info 'caught interrupt, will stop'; exit 2" INT

Inotify is a file system monitoring mechansim. The inotifywait can be used in many complex scenarios. It requires inotify-tools package. As an example, the following snippet use inotifywait to montor a directory, and trigger rsync upon changes



inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' \
-e create,delete,modify,attrib $SRCDIR | while read DATE TIME DIR FILE; do
   rsync -avze 'ssh' $SRCDIR root@${DESTHOST}:${DESTHOSTDIR} &>/dev/null && \
   echo "At ${TIME} on ${DATE}, file $FILECHANGE was backed up via rsync" >> /var/log/filesync.log

The example above shows how to copy a file to a remote server upon change. There is a simpler alternative to it, a tool called lsyncd, which combines rsync and inotify. lsyncd is a linux package (can be installed with yum) and remains an open source project.

The configuration is done in LUA language. Here is a simple example:

settings {
    logfile    = "/var/log/lsyncd/lsyncd.log",
    statusFile = "/var/log/lsyncd/lsyncd.stat",
    statusInterval = 1

    delay = 10,

In this example, we tell lsyncd to use rsyncssh mechanism and it can use hosts defined in openssh configuration (e.g. ~/.ssh/config). For more than one hosts, we can declare the sync section more than once. Full documentation is here.