Elegant way to pass arguments to a bash script

When I started to write bash scripts, I found that it was really convenient to use the basic way to pass arguments with $1 $2 and so on.

It’s quick and easy to write, but not very flexible because the argument order maters and you need to write a check condition.

When I discovered the getopts option, it made my scripts way better. In the following example, I added a function named “commands” that executes the command if the dry-run flag is not set and just display the command if not

Another interesting arg is the “set -x” command, that prints all the command executed by the script.

#!/bin/bash
DRY_RUN=0
function commands {
    if [[ $DRY_RUN -eq 0 ]];then
        echo "Executed command : $1"
        $1
    else
        echo "DRYRUN, Command to be executed : $1"
    fi
}

while getopts "v?d?h?a:b:" ARG; do
  case $ARG in
    v)
      set -x
      echo "Started in Verbose Mode"
      ;;
    d)
      DRY_RUN=1
      echo "Started in Dry Run mode"
      ;;
    h)
      echo "Help"
      ;;
    a)
      ARGA=$OPTARG
      echo "This is the a flag : $ARGA "
      ;;
    b)
      ARGB=$OPTARG
      echo "This is the b flag : $ARGB "
      ;;
  esac
done

if [[ $DRY_RUN -eq 0 ]];then echo "Script Started in No Dry Mode";fi
echo "Script started in Verbose mode " >&2 > /dev/null
commands $ARGA
commands $ARGB

Let’s say I want to pass “ls” to the -b argument :

% bash getopts_example.sh -b ls 
This is the b flag : ls
Script Started in No Dry Mode
Execute command : ls
file1.txt file2.txt getopts_example.sh

I’ll pass ls with the verbose flag -v  :

% bash getopts_example.sh -v  -b ls
+ echo 'Started in Verbose Mode'
Started in Verbose Mode
+ getopts 'v?d?h?a:b:' ARG
+ case $ARG in
+ ARGB=ls
+ echo 'This is the b flag : ls '
This is the b flag : ls
+ getopts 'v?d?h?a:b:' ARG
+ shift 3
+ [[ 0 -eq 0 ]]
+ echo 'Script Started in No Dry Mode'
Script Started in No Dry Mode
+ echo 'Script started in Verbose mode '
+ commands ls
+ [[ 0 -eq 0 ]]
+ echo 'Execute command : ls'
Execute command : ls
+ ls
file1.txt               file2.txt               getopts_example.sh

Now,  with dry-run :

% bash getopts_example.sh  -b ls  -d
This is the b flag : ls
Started in Dry Run mode
Script Started in Dry Mode
DRYRUN, Command to be executed : ls

These small improvements can make the development and debug of bash scripts easier.

Leave a Reply

Your email address will not be published. Required fields are marked *