Reputation: 121407
AFAICT, anything inside a single quotes shouldn't be expanded. Bash manual says:
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.
However, in an older bash version this doesn't appear to be true in Bash 3.00.15(1)-release
.
For example, consider (this is a contrived example of a bigger script):
#!/bin/bash
func() {
local -a cmds=('echo subshell echo hi')
for cmd in "${cmds[@]}"; do
echo "cmd: $cmd"
done
}
func
prints:
cmd: echo
cmd: subshell
cmd: echo
cmd: hi
whereas I expected:
cmd: echo subshell echo hi
This is not an issue in newer bash versions. The above works as expected in Bash 3.2.25(1)-release
and 4.3.46(1)-release
.
Is this a bug in older bash shells? How can work around it so that single quoting preserves values (as I expected above) in bash 3.00.15(1)-release
?
Upvotes: 3
Views: 128
Reputation: 531708
At least in bash
3.00.16 (the closest I could compile without manually patching 3.00), the bug appears to be related including the assignment in the local
command. The following produces the expected output:
func() {
local -a cmds
cmds=('echo subshell echo hi')
for cmd in "${cmds[@]}"; do
echo "cmd: $cmd"
done
}
func
This isn't specific to local
; it appears to be a problem with processing assignments that appear as arguments.
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
Upvotes: 4