假设我已经定义了一个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 "$@"