转移;使用 bash 时的 Shift 与 Shift 2

转移;使用 bash 时的 Shift 与 Shift 2

遇到过一些shift; shift比使用 bash 时更好的 语句shift 2,但我需要一些令人信服的解释。shift; shift如果位置参数的传递方式出现问题,会发生什么以及如何更好地处理问题?

答案1

shift 2如果只有一个位置参数,则失败,并且它树叶该参数在那里:

$ set -- abc
$ shift; shift
$ echo "exit status $? args left $# first arg expands to '$1'"
exit status 1 args left 0 first arg expands to ''

$ set -- abc
$ shift 2
$ echo "exit status $? args left $# first arg expands to '$1'"
exit status 1 args left 1 first arg expands to 'abc'

两者均显示退出状态 1,因为最新的退出状态shift在两种情况下均失败。只是在第一种情况下,第一个shift已经清除了单独的位置参数。

那是巴什的事。在某些 shell 中,尝试移动比实际数量更多的位置参数甚至会导致 shell 退出并出现错误:

$ dash -c 'set -- abc; shift 2; echo end'
dash: 1: shift: can't shift that many

这可能会出现在参数解析循环中,例如,如果您有

while [ "$#" -gt 0 ]; do
    # ...
    if [ "$1" = -f ]; then
        file=$2
        shift 2;
    fi
done`

然后在之后不带任何参数的给出-f将使 Bash 陷入无限循环。对于双精度,shift它只是设置file为空字符串,这可能会在稍后给出更有意义的错误(例如“找不到文件”)。当然,通过检查是否$2已设置或使用,可以更正确地做到这一点getopt,但无论如何。

答案2

shift 2在有两个或多个位置参数的情况下,和两次之间没有区别shift

在只有一个位置参数的情况下,shift 2不会将该值移出列表,并且会以非零退出状态退出。另一方面,运行shift两次显然会从第一个 的列表中删除该值shift。第二个shift仍将以非零退出状态终止。

相关内容