遇到过一些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
仍将以非零退出状态终止。