Search code examples
bashwhile-loopsyntaxcommand-line-arguments

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


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!


Solution

  • 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.