调用shift 1后取消shift args

调用shift 1后取消shift args

我有这样的场景

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_argis 为空或未设置,则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 结尾,并在同一行上跟随另一个语句(换行符是命令终止符,就像 一样;)。

相关内容