Skip to main content

I made a GIF!

Handling shell script command line arguments with getopt and case

Below is a short BASH scripting example how to use getopt and case together and provide better script command line argument handling than simple if-then-else.  It accepts out of order arguments, multiple methods for the same argument (short and long), and ignores unrecognized arguments.

The script itself writes a ISO formatted date and time stamp to a file.  The default options for the number of iterations (count), the interval between iterations (sleep) and the output  file (write) can all be specified from the command line when running the script.

#!/bin/bash

usage () {
echo -e "Usage: tick.sh [-c #] [-s #] [ -w FILE ]"
echo -e "\t\t -c, --count= \t count for iterations to run (integer, default infinite)"
echo -e "\t\t -s, --sleep= \t sleep between iterations (integer, default 5)"
echo -e "\t\t -w, --write= \t write output to file (file system path, default ./tick-ISODATETIME.log)"
echo -e "\t\t -h, --help \t help"
}

debug () {
if [[ -z $boolQuiet ]] ; then
echo -e "intCount =\t$intCount"
echo -e "intSleep =\t$intSleep"
#echo -e "strTimeStamp =\t$strTimeStamp"
#echo -e "strLogFileName =\t$strLogFileName"
#echo -e "strLogFileDir =\t$strLogFileDir"
echo -e "strLogOutput = \t$strLogOutput"
if [[ -z intCount ]]; then
echo "Script tick.sh running INfinite iterations. Press to cancel."
else
echo "Script tick.sh running finite iterations. Wait for prompt to return."
fi
fi
}

## NOTE: This requires GNU getopt; BASH built-in getopts is not equivalent
strGetOpt=`getopt --options c:s:w:qh --longoptions count:,sleep:,write:,quiet,help -- "$@"`

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

## NOTE: quotes around $strGetOpt' are essential
eval set -- "$strGetOpt"

while [ $# -gt 0 ]; do
case "$1" in
-c | --count ) intCount="$2";;
-s | --sleep ) intSleep="$2";;
-w | --write ) strLogOutput="$2";;
-q | --quiet ) boolQuiet="1";;
-h | --help ) usage; exit 0;;
-- ) break;;
esac
shift
done

if [[ -z $strLogOutput ]]; then
strTimeStamp="$(date "+%Y%m%dT%T%:z")"
strLogFileName="tick-$strTimeStamp.log"
strLogFileDir="."
strLogOutput="$strLogFileDir/$strLogFileName"
fi

if [[ -z $intSleep ]]; then
intSleep="5"
fi


if [[ -z $intCount ]]; then
debug
while : ; do
echo "$(date "+%Y%m%dT%T:%N%:z")" >> "$strLogOutput"
sleep $intSleep
done
else
debug
i=$intCount
while [ $i -gt 0 ]; do
echo "$(date "+%Y%m%dT%T:%N%:z")" >> "$strLogOutput"
(( i-- ))
sleep $intSleep
done
fi

#echo -e "tick completed. Output written to:\t\"$strLogOutput\""

exit 0

#EOF

Comments

Popular posts from this blog

Cisco ASA ICMP packet-tracer

Occasionally devices fail to respond to a ping.  This can result from devices being off-line, having a local firewall enabled or the perimeter firewall configuration.  The Cisco ASA ICMP packet-tracer options differ from the TCP or UDP command options.  An example is below: packet-tracer input outside icmp A.B.C.D 8 0 E.F.G.H The ICMP type is "8" (echo request) with code"0" (none).  There are no options on destination IPv4 address E.F.G.H. Complete ICMP documentation at URL http://www.iana.org/assignments/icmp-parameters/ Complete Cisco ASA packet-tracer documentation at URL http://www.cisco.com/en/US/docs/security/asa/asa80/command/reference/p.html#wp1878788

Xfce4 lock screen not working

Xfce4 would not start a screensaver on my Linux system.  Researching it, it ran xflock4 from the command line ad received an error: Property "/general/LockCommand" does not exist on channel "xfce4-session". To fix this, additional configuration needed, but no hacks. First, verify xflock4 and xfconf-query are available. $ which xflock4 xfconf-query /bin/xflock4 /bin/xfconf-query Next  install a lock screen package that provides 'xlock', 'slock', 'i3lock' or similar.  $ sudo yum install -y xlockmore-gtk i3lock Last, add an executable (with options) as /general/LockCommand in the xfce4-session settings. $ xfconf-query -c xfce4-session --create -p /general/LockCommand --set "xlock -mode matrix" --type  string $ xfconf-query -c xfce4-session --create -p /general/LockCommand --set "i3lock -c 000000" --type string Test by running xflock4 from the command line or through the GUI.

X11 Forwarding issue solved

TL;DR Disabling IPv6 necessitates SSHd AddressFamily is "inet" for X11 Forwarding to work. Issue OpenSSH assumes both IPv6 and IPv4 protocols are enabled, and default SSHd AddressFamily value "any" is valid. Quickly skimming the OpenSSH source code, it was not obvious why SSHd does not fail gracefully, selecting only an available IP address family. Therefore, for X11 Forwarding to work correctly, in /etc/ssh/sshd_config we must choose: Defaults - IPv6 enabled and SSHd AddressFamily value " any " Custom - IPv6 disabled and SSHd AddressFamily value " inet " Background PuTTY was not creating a $HOME/.Xauthority file on ssh login and no X11 applications would run, despite setting $DISPLAY.  PuTTY was correctly configured with: X11 Forwarding enabled X display location empty Remote authentication protocol MIT-Magic-Cookie-1 X authority file for local display empty On the initial ssh login there should be a .Xauthority notic