如何在bash脚本中将参数转发给其他命令?

250
在我的bash脚本中,我想解析零个、一个或两个参数(脚本能够识别它们),然后将其余的参数转发给在脚本中调用的命令。我该怎么做?
3个回答

342

使用内置命令shift来“吃掉”参数,然后调用子进程并传递"$@"参数以包括所有剩余的参数。请注意引号,它们应该保留,因为它们导致参数列表的扩展得到正确的引用。


33
"$@" 比 $* 更安全。 - pixelbeat
1
@pixelbeat:谢谢,发现得好。我已经编辑了。 @Łukasz Lew:在手册中查看链接的页面。 :) 基本上,它更好地处理引用。 - unwind
27
$@ 将数组的每个元素都视为引号括起来的字符串,不会被展开。它还确保将每个元素视为一个单独的词语。这段说明以及演示差异的测试脚本可以在此链接中找到:http://tldp.org/LDP/abs/html/internalvariables.html#APPREF - Cascabel
3
注意使用引号!在这里阅读更多有关为什么重要的内容:https://dev59.com/ZW445IYBdhLWcg3wgqnT#4824637 - Cadoiz
2
为了澄清我之前在尝试这个解决方案之前的一个问题:"$@" 不像 C 语言系列中的 sys.argv[0] 一样将脚本/命令名称本身作为参数传递。换句话说,你可以放心地调用任何命令,如 cmd_inside_script "$@" - axolotl
显示剩余4条评论

62

Bash支持参数子集(请参见子集和子字符串),因此您可以像这样选择要处理/传递的参数。

  1. 打开新文件并进行编辑: vim r.sh

    echo "params only 2    : ${@:2:1}"
    echo "params 2 and 3   : ${@:2:2}"
    echo "params all from 2: ${@:2:99}"
    echo "params all from 2: ${@:2}"
    
  2. 运行它:

    $ chmod u+x r.sh
    $ ./r.sh 1 2 3 4 5 6 7 8 9 10
    
  3. 结果为:

    params only 2    : 2
    params 2 and 3   : 2 3
    params all from 2: 2 3 4 5 6 7 8 9 10
    params all from 2: 2 3 4 5 6 7 8 9 10
    

50

bash 使用 shift 命令:

例如: shifttest.sh:

#!/bin/bash
echo $1
shift
echo $1 $2

运行shifttest.sh 1 2 3 的输出结果为

1
2 3

2
@TamásZahola 能解释一下吗? - Kyle Chadha
4
如果你在不将参数引用为"$1"的情况下将其作为$1转发,那么shell将执行单词分割,因此例如foo bar将被分别转发为foobar - Tamás Zahola
阅读更多关于为什么在这里需要双引号的重要性:https://dev59.com/ZW445IYBdhLWcg3wgqnT#4824637 - Cadoiz
3
我的大脑把“shifttest”中的一些字母搞混了,因此我错误地读成了其他单词。 - Alex
1
@TamásZahola,你刚刚救了我的命。谢谢你。 - Alkis Mavridis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接