Home > Enterprise >  Bash while() loop :: Does this process cmd line arguments?
Bash while() loop :: Does this process cmd line arguments?

Time:11-08

I'm a Bash newbie, and I'm puzzling through a Bash script where I see this:

while [ $# -ge 2 ]
  if [ "x$1" = "x-a" ]; then
    echo "STR_A = $2" >>tmpFile.txt
    ...do more stuff...
  elif [ "x$1" = "x-b" ]; then
    echo "STR_B = $2" >>tmpFile.txt
    ...do more stuff...
  else
    usage
done

The script takes in four (or five?) command line arguments, and that usage function is:

usage() {
   echo "usage: myscript -a STR_A | -b STR_B" 1>&2
   exit 1
}

So suppose I ran the script like this:

me@ubuntu1:~$./myscript -A apple -B banana

I'm guessing that this code processes the script's command line arguments. I think that the outer while() loop steps through the command line arguments after argument 1, which would be myscript. The inner if() statements check to see an -a or -b flag is used to supply arguments, and then records the text string that follows in tmpFile.txt. Anything outside of those parameters is rejected and the script exits.

A lot of these assumptions rest on the bet that the outer while() loop...

while [ $# -ge 2 ]

...means "parse the BASH argv[] after the first argument", (to put this in C terms.) If that's not a correct assumption, then I have no idea what's going on here. Any feedback is appreciated, thank you!

CodePudding user response:

This doesn't help understand the code you're reading, but I do option parsing like this:

# inititialize vars, not strictly required in this case
a=''
b=''

# process options
while getopts "ha:b:" opt; do
    case $opt in
        a) a=$OPTARG ;;
        b) b=$OPTARG ;;
        *) usage     ;;
    esac
done

# shift after the processing
shift $((OPTIND - 1))

# look for error conditions
if [[ -n $a && -n $b ]]; then
    echo "only one of -a or -b should be given" >&2
    exit 1
fi

getopts is a bash builtin

CodePudding user response:

Some code explanation.

while [ $# -ge 2 ]

There is a missing do for the loop.

This should loop forever if there are two or more arguments, unless shift is used. If there are less than two arguments, the loop does not even start.

  if [ "x$1" = "x-a" ]; then

In distant past, it was common to prevent empty strings by adding an extra letter. Nowadays you would if [ "$1" = "-a" ]; then.

  else
    usage

Note that the usage is called from within the loop. So, if I would call the script as myscript -a, I would not get a usage message. On the other hand, if I would myscript bla bla, I would get an endless stream of error messages, which is probably not what you want.

I would seriously edit the script; determine whether the while is indeed a loop-forever or whether it is used instead of an if, and try the getops for argument parsing.

  • Related