Mike S
Mike S

Reputation: 1613

Why does shift with an argument cause an infinite loop in this bash script?

I have the following bash script:

#!/bin/bash

while (( "$#" )); do

  case $1 in
    --foo)
      foo=$2
      ;;
    --bar | -b)
      bar=$2
      ;;
    *)
      echo "what?"
      ;;
  esac

  shift
  shift

done

echo $foo
echo $bar

If I run ./my_script.sh -b first --foo second --third I get

what?
second
first

But if I change the two shift statements to a single shift 2 I just get an infinite loop of what?s. What difference between shift; shift and shift 2 causes this?

Upvotes: 2

Views: 299

Answers (1)

rici
rici

Reputation: 241821

From the bash manual documentation of shift n:

If n is zero or greater than $#, the positional parameters are not changed.

So if $# is 1 and you execute shift 2, nothing happens but the return status will be non-zero, indicating failure.

Posix requires that the argument n be no greater than $#. If you fail to ensure that, the script might be terminated (if it is not interactive) or the shift command might terminate with a non-zero status. So even aside from this particular problem, portable code should not use shift n unless it is known that there are at least n arguments.

Upvotes: 4

Related Questions