为什么带参数的 shift 会导致此 bash 脚本中的无限循环?

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

我有以下 bash 脚本:

#!/bin/bash

while (( "$#" )); do

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

  shift
  shift

done

echo $foo
echo $bar

如果我运行./my_script.sh -b first --foo second --third我得到

what?
second
first

但是,如果我将两个 shift 语句更改为单个 shift 2,我只会得到 what? 的无限循环。 shift; shiftshift 2 之间的区别是什么?

来自 shift nbash manual 文档:

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

因此,如果 $# 为 1 并且您执行 shift 2,什么也没有发生,但 return 状态将为非零,表示失败。

Posix 要求参数 n 不大于 $#。如果您无法确保这一点,脚本可能会终止(如果它不是交互式的)或者 shift 命令可能会以非零状态终止。因此,即使不考虑这个特殊问题,可移植代码也不应使用 shift n,除非已知至少有 n 个参数。