Process all arguments except the first one (in a bash script)
我有一个简单的脚本,其中第一个参数是为文件名保留的,所有其他可选参数都应该传递到脚本的其他部分。
使用谷歌,我找到了这个wiki,但它提供了一个字面上的例子:
我不能让其他东西去工作,比如:
或
我从终点站得到了"坏的替代品"。
问题是什么,除了传递给bash脚本的第一个参数之外,我如何处理其他所有参数?
- 为了引起其他人的困惑,提供了错误的shebang,导致"{@:2}"无法工作,这就是正确答案与上面匹配的原因。
- 您刚刚使用了默认shell,它在Ubuntu和许多其他Linux上是dash。在破折号中"$@:-1"被解释为:参数:-字-使用默认值,如果参数未定义或为空,则使用字。所以在破折号中"$@":-1"的结果与"$@"完全相同。要使用bash,只需在脚本文件中使用以下第一行:!/BI/BASH
使用此:
以下语法:
也可以,但不建议这样做,因为正如@gordon已经解释过的那样,使用*,它将所有参数作为带空格的单个参数一起运行,而@保留它们之间的分隔符(即使某些参数本身包含空格)。它与echo没有什么区别,但它对许多其他命令很重要。
- 我刚意识到我的shebang是坏的:#!/usr/bin/env sh,这就是我遇到问题的原因。你的例子工作得很好,和上面提供的一样,在我移除了shebang之后
- 使用"${@:2}"代替——使用*将所有参数作为带空格的单个参数一起运行,而@保留它们之间的分隔符(即使某些参数本身包含空格)。这一区别在echo中并不明显,但在许多其他方面却很重要。
- @戈登戴维森,这里的重点是把论点放在一起。如果我们传递文件名,你就对了。echo足够宽泛,可以为您连接它们;其他命令可能不太好。不要只使用其中的一个或另一个:了解*和@之间的区别,以及何时使用它们。你应该平等地使用它们。一个很好的例子说明什么时候会出现问题:如果$3包含一个换行符(
),它将被替换为一个空格,前提是您有一个默认的$IFS变量。
- @Zenexer:据我所知,问题是如何将除第一个论点以外的所有论点传递给"脚本的其他部分",echo只是用作示例,在这种情况下,它们不应该一起运行。在我的经验中,你希望它们一起运行的情况是罕见的(举个例子来看这个问题),而且"$@"几乎总是你想要的。另外,只有当$@或$*不在双引号中时,才会出现换行的问题。
- @戈登戴维森嗯…你说得对,现在我想起来了;换行不应该是个问题。我一定在想别的事情。但是,我仍然不同意一起运行它们;我需要在脚本中经常使用$*。
- 谷歌shell风格指南fwiw说,"$@"几乎每次都是对的,$*几乎每次都是错的。在样式指南中有更多关于原因的信息。
- 这个语法的名称是什么?
- @艾迪生:这是这里描述的"参数:偏移量"语法。
如果你想要一个同样适用于/bin/sh的解决方案,试试看。
1 2 3 4
| first_arg="$1"
shift
echo First argument:"$first_arg"
echo Remaining arguments:"$@" |
shift [n]将位置参数移动n次。shift将$1的值设为$2的值,$2的值设为$3的值,依此类推,将$#的值减一。
- +1:在转移变量之前,您应该先将$1存入变量中。
- 令人惊讶的是,foo=shift并没有达到我的预期。
- 我知道这是旧的,但是试试看。
- @Raumaankidwi不工作的原因有两个:1)shift在shell中没有任何输出。它只是丢弃了$1,并把所有的东西都转移了。2)$(...)启动一个子shell,它有自己的局部参数。它改变子shell中的参数,这不会影响父级
http://wiki.bash-hacker.org/scripting/posparams
它解释了shift的使用(如果您想放弃前n个参数),然后实现大规模使用(查找标题为该标题的标题)。