处理除第一个之外的所有参数(在bash脚本中)

the*_*eta 401 bash shell

我有一个简单的脚本,其中第一个参数是为文件名保留的,所有其他可选参数应该传递给脚本的其他部分.

使用Google我发现了这个wiki,但它提供了一个文字示例:

echo "${@: -1}"
Run Code Online (Sandbox Code Playgroud)

我无法得到任何其他工作,例如:

echo "${@:2}"
Run Code Online (Sandbox Code Playgroud)

要么

echo "${@:2,1}"
Run Code Online (Sandbox Code Playgroud)

我从终端得到"坏替换".

问题是什么,除了传递给bash脚本的第一个参数外,我该如何处理?

Oli*_*rth 593

用这个:

echo "${@:2}"
Run Code Online (Sandbox Code Playgroud)

以下语法:

echo "${*:2}"
Run Code Online (Sandbox Code Playgroud)

也可以工作,但是不推荐,因为正如@Gordon已经解释过的那样,使用*它会将所有参数作为带有空格的单个参数一起运行,同时@保留它们之间的中断(即使某些参数本身包含空格) ).它并没有什么不同echo,但它对许多其他命令很重要.

  • 使用`"$ {@:2}"而不是 - 使用`*`将所有参数作为带有空格的单个参数一起运行,而`@`保留它们之间的断点(即使某些参数本身包含空格) ).`echo`的区别并不明显,但对许多其他事情都很重要. (108认同)
  • 我刚刚意识到我的shebang很糟糕:`#!/ usr/bin/env sh`这就是我遇到问题的原因.在我删除了shebang之后,你的示例工作正常,与上面提供的相同 (5认同)
  • @GordonDavisson 这里的重点是一起运行参数。如果我们传递文件名,你会是正确的。`echo` 足够宽容,可以为您连接它们;其他命令可能不太好。不要只使用一个或另一个:了解 `*` 和 `@` 之间的区别,以及何时使用它们。您应该大致平等地使用它们。一个很好的例子说明何时会出现问题:如果 `$3` 包含一个换行符(`\n`),它将被一个空格替换,前提是你有一个默认的 `$IFS` 变量。 (3认同)

Ben*_*son 168

如果你想要一个也可以/bin/sh尝试的解决方案

first_arg="$1"
shift
echo First argument: "$first_arg"
echo Remaining arguments: "$@"
Run Code Online (Sandbox Code Playgroud)

shift [n]将位置参数移动n次.A shift将值设置为值$1的值$2,将值设置$2为值$3,依此类推,将值减$#1.

  • +1:你应该在将它移走之前将$ 1保存到变量中. (24认同)
  • @raumaankidwai这不起作用有两个原因:1)`shift`(在shell中)没有任何输出.它只丢弃了"$ 1"并将所有内容都降低了.2)`$(...)`启动一个子shell,它有自己的本地参数.它会移动子shell中的参数,这不会影响父级 (10认同)
  • 令人惊讶的是,'foo = shift`并没有达到我的预期. (3认同)
  • 谢谢:)有没有什么办法可以做到`somecommand "$1" "${@:2}"`用这个方法所做的事情(即移位“内联”)? (2认同)

wal*_*tes 14

在 bash 4 或更高版本中工作:

#!/bin/bash
echo "$0";         #"bash"
bash --version;    #"GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)"
Run Code Online (Sandbox Code Playgroud)

在功能上:

echo $@;              #"p1" "p2" "p3" "p4" "p5"
echo ${@: 0};  #"bash" "p1" "p2" "p3" "p4" "p5"
echo ${@: 1};         #"p1" "p2" "p3" "p4" "p5"
echo ${@: 2};              #"p2" "p3" "p4" "p5"
echo ${@: 2:1};            #"p2"
echo ${@: 2:2};            #"p2" "p3"
echo ${@: -2};                       #"p4" "p5"
echo ${@: -2:1};                     #"p4"
Run Code Online (Sandbox Code Playgroud)

注意':'和'-'之间的空格,否则表示不同:

${var:-word}如果 var 为空或未设置,
则用 word 替换 var。var 的值不会改变。

${var:+word}如果设置
了 var ,则用 word 替换 var。var 的值不会改变。

描述于:Unix / Linux - Shell Substitution