Ale*_*lls 8 shell bash arguments
我有这个场景
first_arg="$1";
if foo; then
shift 1;
node foo.js "$@"
elif bar; then
shift 1;
node bar.js "$@"
elif baz; then
shift 1;
node baz.js "$@"
else
node default.js "$@"
fi
Run Code Online (Sandbox Code Playgroud)
我想把上面的变成这样:
first_arg="$1";
shift 1;
if foo; then
node foo.js "$@"
elif bar; then
node bar.js "$@"
elif baz; then
node baz.js "$@"
else
unshift 1;
node default.js "$@"
fi
Run Code Online (Sandbox Code Playgroud)
但我不确定是否有像 unshift 这样的操作符,这是我刚刚编出来的。一种解决方法可能是这样的:
node default.js "$first_arg" "$@"
Run Code Online (Sandbox Code Playgroud)
但是当我尝试这样做时,我得到了奇怪的行为。
Ini*_*ian 13
您永远不需要首先使用shift 1。只需使用位置参数并围绕它们的索引切片来传递参数。
first_arg="$1"
Run Code Online (Sandbox Code Playgroud)
完成此操作后,其余参数可以作为"${@:2}". 该符号是一种表示从位置参数 2 到列表末尾的方法。
为您的示例使用构造将是
node foo.js "${@:2}"
Run Code Online (Sandbox Code Playgroud)
最后else一部分做
node default.js "$1" "${@:2}"
Run Code Online (Sandbox Code Playgroud)
这与"$@"没有完成位置参数移位相同。
您可以将参数保存在数组中:
args=( "$@" ) # use double quotes
shift 1
if foo; then
node foo.js "$@"
elif bar; then
node bar.js "$@"
elif baz; then
node baz.js "$@"
else
node default.js "${args[@]}"
fi
Run Code Online (Sandbox Code Playgroud)
你尝试的事情:
first_arg=$1
shift
# ...later...
else
node default.js "$first_arg" "$@"
fi
Run Code Online (Sandbox Code Playgroud)
如果至少有一个命令行参数,这将与您的第一个变体相同。
没有命令行参数"$first_arg"仍然是一个空字符串,因此是一个参数,而"$@"不会生成一个空字符串。
如果您的 Node 应用程序在命令行上接受一个空参数,那么这可能会使应用程序在您的两个代码变体中的行为有所不同。
如果在没有命令行参数的情况下调用您的脚本是一件有效的事情,您可以这样做
node default.js ${first_arg:+"$first_arg"} "$@"
Run Code Online (Sandbox Code Playgroud)
${first_arg:+"$first_arg"}如果first_arg为空或未设置,则where将扩展为空,但"$first_arg"如果first_arg设置为非空字符串。或者,如果要导致未设置或空变量的显式失败:
node default.js "${first_arg:?Error, no command line arguments}" "$@"
Run Code Online (Sandbox Code Playgroud)
替代方法包括制作Jesse_b 在他的回答中显示$@的bash数组副本。
把$first_arg回$@用
set -- "$first_arg" "$@"`
Run Code Online (Sandbox Code Playgroud)
不会因为这样的工作将包括一个空的说法是$1在$@如果在命令行参数失踪。
和
set -- ${first_arg:+"$first_arg"} "$@"`
Run Code Online (Sandbox Code Playgroud)
如果$first_arg为空或变量不存在,您将不会“取消移动”任何内容。
请注意,shift 与 shift 1 相同,并且单个语句不需要以 ; 结束。除非在同一行上跟随另一个语句(换行符是命令终止符,就像;)。