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

Ver*_*era 3 bash

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

ilk*_*chu 7

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'
Run Code Online (Sandbox Code Playgroud)

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

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

$ dash -c 'set -- abc; shift 2; echo end'
dash: 1: shift: can't shift that many
Run Code Online (Sandbox Code Playgroud)

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

while [ "$#" -gt 0 ]; do
    # ...
    if [ "$1" = -f ]; then
        file=$2
        shift 2;
    fi
done`
Run Code Online (Sandbox Code Playgroud)

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


Kus*_*nda 5

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

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