我有这样的场景
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
我想把上面的变成这样:
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
但我不确定是否有像unshift这样的运算符,这是我刚刚编造的。一种解决方法可能是这样的:
node default.js "$first_arg" "$@"
但当我尝试这样做时,我的行为很奇怪。
答案1
shift 1
首先,您不需要使用。只需使用位置参数并切片其索引即可传递参数。
first_arg="$1"
一旦执行此操作,其余参数就可以作为 访问"${@:2}"
。该符号是一种表示从位置参数 2 到列表末尾的方法。
使用您的示例的构造将是
node foo.js "${@:2}"
对于最后else
一部分,请执行以下操作:
node default.js "$1" "${@:2}"
"$@"
这与没有进行位置参数转换时的情况相同。
答案2
您可以将参数保存在数组中:
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
答案3
你尝试过的事情:
first_arg=$1
shift
# ...later...
else
node default.js "$first_arg" "$@"
fi
如果至少有一个命令行参数,这将与您的第一个变体相同。
如果没有命令行参数,"$first_arg"
仍然会是一个空字符串,因此也是一个参数,而"$@"
甚至不会生成空字符串。
如果您的 Node 应用程序在命令行上接受空参数,则这可能会使应用程序在两个代码变体中的行为有所不同。
如果不使用命令行参数调用脚本是有效的做法,那么您可以这样做
node default.js ${first_arg:+"$first_arg"} "$@"
${first_arg:+"$first_arg"}
如果first_arg
is 为空或未设置,则where将扩展为空,但"$first_arg"
如果first_arg
设置为非空字符串,则扩展为空。或者,如果您想导致未设置或空变量的显式失败:
node default.js "${first_arg:?Error, no command line arguments}" "$@"
替代方案包括将 复制$@
为bash
数组正如 Jesse_b 在他的回答中所示。
放回与$first_arg
$@
set -- "$first_arg" "$@"
不起作用,因为这将包含一个空参数,就像$1
缺少$@
命令行参数一样。
和
set -- ${first_arg:+"$first_arg"} "$@"
$first_arg
如果为空或变量不存在,则不会“取消移动”任何内容。
请注意,shift
与 相同,shift 1
并且单个语句不需要以;
except 结尾,并在同一行上跟随另一个语句(换行符是命令终止符,就像 一样;
)。