联合操作
对于涉及的两个shell,所给出的示例将假定已明确设置了argv列表:
$ set -- "first entry" "second entry" "third entry"
在两个Shell中,
declare -p
可以用于以明确的形式输出变量名的值,但它们表示该形式的方式可能会有所不同。
在bash中
bash中的扩展规则通常与ksh和POSIX sh语义兼容。与这些Shell兼容需要未加引号的扩展执行字符串拆分和全局匹配(例如将
*
替换为当前目录中的文件列表)。
在变量赋值中使用圆括号会使它成为一个数组。比较下面这三个赋值的区别:
$ arr_str=$@
$ declare -p arr_str
declare -- arr="first entry second entry third entry"
$ arr=( $@ )
declare -a arr='([0]="first" [1]="entry" [2]="second" [3]="entry" [4]="third" [5]="entry")'
$ arr=( "$@" )
$ declare -p arr
declare -a arr='([0]="first entry" [1]="second entry" [2]="third entry")'
同样,在展开时,引号和Sigil很重要:
$ printf '%s\n' "$arr"
first entry
$ printf '%s\n' $arr
first
entry
$ printf '%s\n' ${arr[@]}
first
entry
second
entry
third
entry
$ printf '%s\n' "${arr[@]}"
first entry
second entry
third entry
在zsh中
zsh尝试使用许多技巧来实现用户的意图,而不是与历史shell(如ksh、POSIX sh等)兼容。然而,即使在这种情况下,做错事情也可能会产生你不想要的结果:
$ arr_str=$@
$ declare -p arr_str
typeset arr_str='first entry second entry third entry'
$ arr=( $@ )
$ declare -p arr
typeset -a arr
arr=('first entry' 'second entry' 'third entry')
$ printf '%s\n' $arr
first entry
second entry
third entry
$ printf '%s\n' $arr_str
first entry second entry third entry
bar=( "$@" )
来防止字符串分割和全局匹配。 - Charles Duffy