数组中的单引号扩展
Single quote expansion within an array
AFAICT,单引号内的任何内容都不应展开。 Bash 手册说:
Enclosing characters in single quotes preserves the literal value of
each character within the quotes. A single quote may not occur
between single quotes, even when preceded by a backslash.
然而,在较旧的 bash 版本中,这在 Bash 3.00.15(1)-release
中似乎并非如此。
例如,考虑(这是一个更大脚本的人为示例):
#!/bin/bash
func() {
local -a cmds=('echo subshell echo hi')
for cmd in "${cmds[@]}"; do
echo "cmd: $cmd"
done
}
func
打印:
cmd: echo
cmd: subshell
cmd: echo
cmd: hi
而我预计:
cmd: echo subshell echo hi
这在较新的 bash 版本中不是问题。以上在 Bash 3.2.25(1)-release
和 4.3.46(1)-release
.
中按预期工作
这是旧 bash shell 中的错误吗?如何解决它,以便单引号保留 bash 3.00.15(1)-release
?
中的值(正如我上面预期的那样)
至少在 bash
3.00.16(我可以在不手动修补 3.00 的情况下编译的最接近的版本)中,该错误似乎与 local
命令中的分配有关。以下产生预期的输出:
func() {
local -a cmds
cmds=('echo subshell echo hi')
for cmd in "${cmds[@]}"; do
echo "cmd: $cmd"
done
}
func
这不是 local
特有的;处理作为参数出现的分配似乎有问题。
bash-3.00$ declare -a foo=('echo bar')
bash-3.00$ printf '%s\n' "${foo[@]}"
echo
bar
bash-3.00$ foo=('echo bar')
bash-3.00$ printf '%s\n' "${foo[@]}"
echo bar
AFAICT,单引号内的任何内容都不应展开。 Bash 手册说:
Enclosing characters in single quotes preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.
然而,在较旧的 bash 版本中,这在 Bash 3.00.15(1)-release
中似乎并非如此。
例如,考虑(这是一个更大脚本的人为示例):
#!/bin/bash
func() {
local -a cmds=('echo subshell echo hi')
for cmd in "${cmds[@]}"; do
echo "cmd: $cmd"
done
}
func
打印:
cmd: echo
cmd: subshell
cmd: echo
cmd: hi
而我预计:
cmd: echo subshell echo hi
这在较新的 bash 版本中不是问题。以上在 Bash 3.2.25(1)-release
和 4.3.46(1)-release
.
这是旧 bash shell 中的错误吗?如何解决它,以便单引号保留 bash 3.00.15(1)-release
?
至少在 bash
3.00.16(我可以在不手动修补 3.00 的情况下编译的最接近的版本)中,该错误似乎与 local
命令中的分配有关。以下产生预期的输出:
func() {
local -a cmds
cmds=('echo subshell echo hi')
for cmd in "${cmds[@]}"; do
echo "cmd: $cmd"
done
}
func
这不是 local
特有的;处理作为参数出现的分配似乎有问题。
bash-3.00$ declare -a foo=('echo bar')
bash-3.00$ printf '%s\n' "${foo[@]}"
echo
bar
bash-3.00$ foo=('echo bar')
bash-3.00$ printf '%s\n' "${foo[@]}"
echo bar