协慌网

登录 贡献 社区

如何将所有传递给我的 bash 脚本的参数传递给我的函数?

假设我已经定义了一个function abc() ,该函数将处理与分析传递给脚本的参数有关的逻辑。

如何将 bash 脚本收到的所有参数传递给它?参数的数量是可变的,所以我不能仅仅对这样传递的参数进行硬编码:

abc $1 $2 $3 $4

编辑。更好的是,我的函数是否可以访问脚本参数的变量?

答案

$@变量扩展为所有用空格分隔的命令行参数。这是一个例子。

abc "$@"

使用$@ ,(几乎)应始终将其放在双引号中,以避免对包含空格或通配符的参数进行错误的解析(请参见下文)。这适用于多个参数。它也可移植到所有 POSIX 兼容的外壳中。

$0 (通常是脚本的名称或路径)不在$@也毫无意义。

Bash 参考手册的 “特殊参数” 部分说, $@扩展为从 1 开始的位置参数。当在双引号内进行扩展时,每个参数都会扩展为一个单独的单词。那就是"$@"等效于"$1" "$2" "$3"...

传递一些参数:

如果要传递除第一个参数以外的所有参数,可以首先使用shift来 “使用” 第一个参数,然后传递"$@"以将其余参数传递给另一个命令。在 bash(以及 zsh 和 ksh,但不是在普通的 POSIX shell 中,例如破折号)中,可以使用数组切片的变体来做到这一点而不会弄乱参数列表: "${@:3}"将使您的参数以"$3" 。如果传递了许多参数, "${@:3:4}"将使您最多可以有四个从"$3"开始的参数(即"$3" "$4" "$5" "$6"

您可能不想做的事情:

"$*"将所有参数组合在一起,形成一个字符串(用空格分隔,或$IFS的第一个字符分隔)。这放宽了参数内的空间参数间的空间之间的区别,因此通常是一个坏主意。尽管可以打印参数,例如echo "$*" ,但您不必担心保留区分之间 / 之间的空格。

将参数分配给常规变量(如args="$@" )将所有参数混在一起,就像"$*"一样。如果要将参数存储在变量中,请使用带有args=("$@")的数组(括号使之成为数组),然后将其引用为"${args[0]}"等。注意在 bash 和 ksh 中,数组索引从 0 开始,因此$1将在args[0] ,以此类推。反之,zsh 在数组索引中从 1 开始,因此$1将在args[1] 。而像 dash 这样的更基本的 shell 根本就没有数组。

$@$*取消双引号将尝试将每个参数拆分为单独的单词(基于空格或$IFS任何内容),还尝试将任何类似于文件名通配符的内容扩展为匹配文件名列表。这可能会产生真正的怪异效果,应几乎始终避免这样做。 (zsh 除外,默认情况下不进行此扩展。)

我需要对此进行更改,我希望它将对其他人有用:

function diffs() {
        diff "${@:3}" <(sort "$1") <(sort "$2")
}

"${@:3}"部分表示数组的所有成员均从 3 开始。因此,此函数通过将前两个参数传递给 diff 进行排序,然后将所有其他参数传递给 diff 来实现排序的 diff,因此您可以类似于 diff 来称呼它:

diffs file1 file2 [other diff args, e.g. -y]

使用$@变量,该变量将扩展为所有用空格分隔的命令行参数。

abc "$@"