如何将传递给我的 bash 脚本的所有参数传递给我的函数? [复制]
Posted
技术标签:
【中文标题】如何将传递给我的 bash 脚本的所有参数传递给我的函数? [复制]【英文标题】:How to pass all arguments passed to my bash script to a function of mine? [duplicate] 【发布时间】:2011-04-18 04:51:07 【问题描述】:假设我定义了一个function abc()
,它将处理与分析传递给我的脚本的参数相关的逻辑。
如何将我的 bash 脚本收到的所有参数传递给它?参数的数量是可变的,所以我不能像这样硬编码传递的参数:
abc $1 $2 $3 $4
编辑。更好的是,我的函数有什么方法可以访问脚本参数的变量吗?
【问题讨论】:
Propagate all arguments in a bash shell script 的可能重复项。 (这个问题实际上是在此处链接的问题之前发布的。但链接中的问题具有更详细的答案和更丰富的标题,可能最好作为参考问题) 【参考方案1】:$@
变量扩展为所有由空格分隔的命令行参数。这是一个例子。
abc "$@"
在使用$@
时,您应该(几乎)始终将其放在双引号中以避免错误解析包含空格或通配符的参数(见下文)。这适用于多个参数。它还可以移植到所有符合 POSIX 标准的 shell。
另外值得注意的是$0
(一般是脚本的名称或路径)不在$@
中。
Bash Reference Manual Special Parameters Section 表示$@
扩展为从一开始的位置参数。当扩展出现在双引号内时,每个参数都扩展为一个单独的单词。即"$@"
等价于"$1" "$2" "$3"...
。
传递一些参数:
如果您想传递除第一个以外的所有参数,您可以首先使用shift
来“使用”第一个参数,然后传递"$@"
以将剩余的参数传递给另一个命令。在 bash(以及 zsh 和 ksh,但不是在像 dash 这样的普通 POSIX shell 中)中,您可以使用数组切片的变体来执行此操作而不会弄乱参数列表:"$@:3"
将为您提供以 "$3"
开头的参数。如果传递了那么多参数,"$@:3:4"
将为您提供从 "$3"
开始的最多四个参数(即"$3" "$4" "$5" "$6"
)。
你可能不想做的事情:
"$*"
将所有参数组合成一个字符串(由空格分隔,或者$IFS
的第一个字符是什么)。这失去了空格 within 参数和空格 between 参数之间的区别,因此通常是一个坏主意。尽管打印参数可能没问题,例如echo "$*"
,前提是您不关心保留区别内/之间的空间。
将参数分配给常规变量(如args="$@"
)会像"$*"
那样将所有参数混合在一起。如果要将参数存储在变量中,请使用带有args=("$@")
的数组(括号使其成为数组),然后将它们引用为例如"$args[0]"
等请注意,在 bash 和 ksh 中,数组索引从 0 开始,因此 $1
将在 args[0]
等中。另一方面,zsh 从 1 开始数组索引,因此 $1
将是在args[1]
。像 dash 这样更基本的 shell 根本没有数组。
省略双引号,使用$@
或$*
,将尝试将每个参数拆分为单独的单词(基于空格或$IFS
中的任何内容),并尝试扩展任何看起来就像文件名通配符到匹配文件名列表中一样。这可能会产生非常奇怪的影响,并且几乎应该始终避免。 (除了在 zsh 中,默认情况下不会发生这种扩展。)
【讨论】:
阅读更多关于为什么在此处使用双 " 很重要:***.com/a/4824637/4575793"$@:3"
似乎不适用于zsh
。
额外注释:$*
将是一个字符串,IFS
的第一个字符是连接元素。
@kvantour 如果$*
用双引号括起来,就会发生这种情况。如果它没有被引用,它会受到分词和通配符扩展的影响,因此它会立即重新拆分回元素 并且 任何包含 $IFS
字符的元素也将被拆分(然后任何通配符都会被拆分)展开)。最终结果:没有双引号,$*
和 $@
最终给出相同的结果。
@DylanYoung 您必须解析它们以确定哪些应该被视为选项参数。例如,在somecmd -a b c -d
中,-a
显然是一个选项,但b
是-a
的一个参数(因此是它的“一部分”),还是一个简单的位置参数?你需要知道-a
是否需要一个参数来决定。此外,如果 -
在第一个位置命令之前,某些命令仅将其识别为指示选项,因此 -d
可能是也可能不是选项,具体取决于此命令使用的策略。【参考方案2】:
我需要对此进行修改,希望对其他人有用:
function diffs()
diff "$@:3" <(sort "$1") <(sort "$2")
"$@:3"
部分表示从 3 开始的数组的所有成员。所以这个函数通过将前两个参数通过 sort 传递给 diff,然后将所有其他参数传递给 diff 来实现排序的 diff,所以你可以调用它类似于 diff:
diffs file1 file2 [other diff args, e.g. -y]
【讨论】:
"$@:3"
在您的脚本有参数时也很棒,但也可以将参数传递给它们调用的其他脚本。例如,我的一个项目有一个用于轻松运行程序的脚本,并带有一个供主类使用的参数。然后"$@:2"
可用于将剩余的参数传递给该入口点。
@Kat 已经提到了这一点,但要澄清一下(以防您仍有疑问):command "$@"
等同于command $1 "$@:2"
。
天啊!我吻你!【参考方案3】:
使用$@
变量,该变量扩展为所有由空格分隔的命令行参数。
abc "$@"
【讨论】:
【参考方案4】:这是一个简单的脚本:
#!/bin/bash
args=("$@")
echo Number of arguments: $#
echo 1st argument: $args[0]
echo 2nd argument: $args[1]
$#
是脚本接收的参数数量。我发现使用数组更容易访问它们:args=("$@")
行将所有参数放在args
数组中。要访问它们,请使用$args[index]
。
【讨论】:
第一个参数是$args[0]
:o
将 $@ 传递到数组中比仅按索引调用参数(例如,$1)有什么好处?
投票同意与@King 的协议,即第一个元素需要在 [0] 处作为数组。
不知何故我错过了它。已修复,谢谢指出。
未来的读者应该注意这个例子中的shebang是不正确的。 sh 不支持数组,这是一个 bash 功能。这可能起作用的唯一原因是,如果您的操作系统已将 /bin/sh
符号链接到 bash,或者您使用 bash script.sh
调用脚本。【参考方案5】:
值得一提的是,您可以使用此语法指定参数范围。
function example()
echo "line1 $@:1:1"; #First argument
echo "line2 $@:2:1"; #Second argument
echo "line3 $@:3"; #Third argument onwards
我没看到有人提到过。
【讨论】:
前两个可以使用$1
, $2
,...
@rubo77 我已经更正了答案的措辞,包括“范围”谢谢。
谢谢,这正是我用变量索引$@
所需要的【参考方案6】:
abc "$@" 通常是正确的答案。
但是我试图将参数传递给 su 命令,并且没有多少引用可以阻止错误su: unrecognized option '--myoption'
。实际上对我有用的是将所有参数作为单个字符串传递:
abc "$*"
我的确切情况(我确定其他人需要这个)在我的 .bashrc 中
# run all aws commands as Jenkins user
aws ()
sudo su jenkins -c "aws $*"
【讨论】:
嘿,OP,看起来你在abc
示例中可能有错字
正是我需要的。我的命令用引号括起来,这是唯一对我有用的东西。
大概是这样的使用方式,但要注意使用字符串参数时的风险。请在此处查看“$*”示例:***.com/a/46205560/4575793(更多关于 '$@' 与 '$*' 以及引用的变体)【参考方案7】:
abc "$@"
$@
表示为您的 bash 脚本提供的所有参数。
【讨论】:
如果不引用$@
会丢失正确的分词
@Daenyth 是对的,请在此处阅读更多信息:***.com/a/4824637/4575793以上是关于如何将传递给我的 bash 脚本的所有参数传递给我的函数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Linux 中使用终端命令将文件参数传递给我的 bash 脚本? [复制]