How to pass all arguments passed to my bash script to a function of mine?
假设我定义了一个function abc(),它将处理与分析传递给脚本的参数相关的逻辑。
如何将bash脚本接收到的所有参数传递给它?参数的数目是可变的,所以我不能硬编码像这样传递的参数:
编辑。更好的是,我的函数是否有任何方法可以访问脚本参数的变量?
- 可能与将所有参数从bash脚本传递到另一个命令重复
pet peeve:当使用$@时,您应该(几乎)总是将其放在双引号中,以避免错误地将带有空格的论点放在引号中:
- 这不是只有一个论点有效吗?如果您有多个参数,它不会作为一个长字符串传递吗?
- @hepcat72号"$*"的工作方式和你描述的一样,但"$@"被壳牌当作一个特殊的案例来处理。从bash参考手册的特殊参数部分:"@…"从一开始扩展到位置参数。当扩展出现在双引号中时,每个参数扩展到单独的单词。也就是说,"$@"相当于"$1""$2"…"
- 如果要传递除第一个参数以外的所有参数,可以首先使用shift来"使用"第一个参数,然后将其余参数的列表$@传递给另一个命令
- @rubo77在bash中(但不是在普通posix shell中),您可以这样做,而不必使用数组切片的变体来干扰参数列表:"${@:3}"将获得以"$3"开头的参数,如果传递了许多参数,"${@:3:4}"将获得最多四个以"$3" (essentially, 开头的参数"$3""$4""$5""$6"。
- 该死的,关于双引号的建议是个救命稻草
- 值得注意的是,$0不在$@中。换言之,给定args=("$@");,那么${args[0]}等于$1,而不是$0。
- 这也适用于posix sh;因此,如果您试图避免依赖bash,那么您仍然很幸运。
我需要一个变化,我希望这对其他人有用:
1 2 3
| function diffs() {
diff"${@:3}" <(sort"$1") <(sort"$2")
} |
"${@:3}"部分是指数组中从3开始的所有成员。因此,此函数通过将前两个参数通过sort传递给diff,然后将所有其他参数传递给diff来实现排序后的diff,因此可以类似地调用diff:
1
| diffs file1 file2 [other diff args, e.g. -y] |
- 当您有具有参数的脚本,但也可以将参数传递给它们调用的其他脚本时,"${@:3}"也非常好。例如,我的一个项目有一个易于运行程序的脚本,其中有一个供主类使用的参数。然后,可以使用"${@:2}"将剩余的参数传递给该入口点。
- @凯特已经提到了这一点,但为了澄清(如果你仍然有疑问):command"$@"相当于command $1"${@:2}"。
使用$@变量,该变量扩展到由空格分隔的所有命令行参数。
下面是一个简单的脚本:
1 2 3 4 5 6 7
| #!/bin/bash
args=("$@")
echo Number of arguments: $#
echo 1st argument: ${args[0]}
echo 2nd argument: ${args[1]} |
$#是脚本接收到的参数数。我发现使用数组更容易访问它们:args=("$@")行将所有参数放在args数组中。要访问它们,请使用${args[index]}。
- 第一个论点是:o
- 谢谢您。很有帮助!
- 将$@传递到数组有什么好处,而不只是通过索引调用参数(例如$1)?
- 投票赞成与@king达成协议,第一个元素的数组必须是[0]。
- 不知怎么的,我错过了。修好了,谢谢你指出。
- @Kingand:它允许轻松地迭代参数。
- 记住:${args[0]}相当于$1而不是$0。因此,如果您希望脚本始终作为根运行,那么您可以在开始时放置if [[ $(id -u) -ne 0 ]]; then sudo"$0""$@"; exit 0; fi。
- 任何未来的读者都应该注意到这个例子中的shebang是不正确的。sh不支持数组,这是一个bash特性。这样做的唯一原因是,如果您的操作系统已将/bin/sh符号链接到bash,或者使用bash script.sh调用脚本。
- @很好,我编辑了我的答案。
值得一提的是,您可以用这种语法指定参数范围。
1 2 3 4 5
| function example() {
echo"line1 ${@:1:1}"; #First argument
echo"line2 ${@:2:1}"; #Second argument
echo"line3 ${@:3}"; #Third argument onwards
} |
我没看到提到过。
- 您只需使用$1、$2……前两个
- @Rubo77我已经更正了我的答案的措辞,包括"范围"谢谢。
$@表示为bash脚本提供的所有参数。
ABC"$@"通常是正确的答案。但是我试图将一个参数传递给su命令,任何引用都不能阻止错误su: unrecognized option '--myoption'。实际上对我有用的是将所有参数作为一个字符串传递:
我的确切情况(我确信还有人需要这个)在我的.bashrc中。
1 2 3 4 5
| # run all aws commands as Jenkins user
aws ()
{
sudo su jenkins -c"aws $*"
} |