Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

quoted and concatenated positional parameters

4 views
Skip to first unread message

gregrwm

unread,
May 23, 2012, 10:47:33 PM5/23/12
to bug-...@gnu.org
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-redhat-linux-gnu'
-DCONF_VENDOR='redhat' -DLOCALEDIR='/usr/share/locale'
-DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include
-I./lib -D_GNU_SOURCE -DRECYCLES_PIDS -O2 -g -pipe -Wall
-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
--param=ssp-buffer-size=4 -m64 -mtune=generic -fwrapv
uname output: Linux okra.fo4.net 2.6.32-042stab053.5 #1 SMP Tue Mar 27
11:42:17 MSD 2012 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-redhat-linux-gnu

Bash Version: 4.1
Patch Level: 2
Release Status: release

Description:
expansion anomaly with quoted and concatenated positional parameters

Repeat-By:
a(){ echo
echo '"${@:2}a3 a2" a$1 #works as long as $1 and 3 are swapped'
echo "${@:2}a3 a2" a$1
"${@:2}a3 a2" a$1
echo $?
a=("${@}");}
b(){ echo
echo '"${@:2}b$1 b2" b3 #fails! why?'
echo "${@:2}b$1 b2" b3
"${@:2}b$1 b2" b3
echo $?
b=("${@}");}
c(){ echo
echo '${@:2}c$1 c2 c3 #works as long as quoting omitted'
echo ${@:2}c$1 c2 c3
${@:2}c$1 c2 c3
echo $?
c=("${@}");}
a x set y z;declare -p a
b x set y z;declare -p b
c x set y z;declare -p c

#output:

#"${@:2}a3 a2" a$1 #works as long as $1 and 3 are swapped
#set y za3 a2 ax
#0
#declare -a a='([0]="y" [1]="za3 a2" [2]="ax")'

#"${@:2}b$1 b2" b3 #fails! why?
#set y zbx b2 b3
#bash: set y zbx b2: command not found
#127
#declare -a b='([0]="x" [1]="set" [2]="y" [3]="z")'

#${@:2}c$1 c2 c3 #works as long as quoting omitted
#set y zcx c2 c3
#0
#declare -a c='([0]="y" [1]="zcx" [2]="c2" [3]="c3")'

Dan Douglas

unread,
May 24, 2012, 1:33:48 AM5/24/12
to bug-...@gnu.org, gregrwm
On Wednesday, May 23, 2012 09:47:33 PM gregrwm wrote:
> expansion anomaly with quoted and concatenated positional parameters

Also reproducible in 4.2.28(1)-release

This occurs when any expansion is adjacent to or contained within a word that
is adjacent to an expansion of the from "$@" or "${a[@]}", and within the same
double-quotes. Bash mistakenly treats "${@}${x}" and "${@}""$x" differently.

> echo '${@:2}c$1 c2 c3 #works as long as quoting omitted'

Because you're applying word-splitting to the result. You'll see that there is
only one word if IFS is set to null. It's impossible to test whether the
unquoted case is correct. The manpage says that only a quoted "$@" is split
into words for reasons other than word-splitting. Bash, mksh, and dash all
disagree about the unquoted cases, while Bash is the only shell to take issue
with the adjacent expansion in all cases.

~ $ for sh in {{,m}k,{d,b}a,z}sh; do printf '%s\n' "${sh}:" "$("$sh" -c "$(</dev/stdin)" -- {1..5})"; echo; done <<"EOF"
args() { printf '<%s> ' "$@"; echo; }
args "${@}${1}"
args "${@}foo"
args ${@}${1}
args ${@}foo
IFS=
args ${@}${1}
args ${@}foo
EOF

ksh:
<1> <2> <3> <4> <51>
<1> <2> <3> <4> <5foo>
<1> <2> <3> <4> <51>
<1> <2> <3> <4> <5foo>
<1> <2> <3> <4> <51>
<1> <2> <3> <4> <5foo>

mksh:
<1> <2> <3> <4> <51>
<1> <2> <3> <4> <5foo>
<1> <2> <3> <4> <51>
<1> <2> <3> <4> <5foo>
<1 2 3 4 51>
<1 2 3 4 5foo>

dash:
<1> <2> <3> <4> <51>
<1> <2> <3> <4> <5foo>
<1> <2> <3> <4> <51>
<1> <2> <3> <4> <5foo>
<123451>
<12345foo>

bash:
<1 2 3 4 51>
<1> <2> <3> <4> <5foo>
<1> <2> <3> <4> <51>
<1> <2> <3> <4> <5foo>
<1 2 3 4 51>
<1> <2> <3> <4> <5foo>

zsh:
<1> <2> <3> <4> <51>
<1> <2> <3> <4> <5foo>
<1> <2> <3> <4> <51>
<1> <2> <3> <4> <5foo>
<1> <2> <3> <4> <51>
<1> <2> <3> <4> <5foo>
--
Dan Douglas
signature.asc

Dan Douglas

unread,
May 24, 2012, 1:53:08 AM5/24/12
to bug-...@gnu.org
Ugh, Sorry, I forgot to strip trailing whitespace. If that wasn't
comprehensible for anyone, the heredoc in the preceeding the testcase was:

args() { printf '<%s> ' "$@"; echo; }
args "${@}${1}"
args "${@}foo"
args ${@}${1}
args ${@}foo
IFS=
args ${@}${1}
args ${@}foo
EOF

--
Dan Douglas

0 new messages