Bug 12776

Summary: $@ containing quoted string is split into separate arguments
Product: Busybox Reporter: Marius <marius>
Component: Standard ComplianceAssignee: unassigned
Status: RESOLVED INVALID    
Severity: normal CC: busybox-cvs
Priority: P5    
Version: 1.31.x   
Target Milestone: ---   
Hardware: Other   
OS: Linux   
Host: Target:
Build:

Description Marius 2020-04-16 10:55:02 UTC
My system is a router (arm-brcm-uclibcgnueabi, armv7l) running kernel 2.26 and busybox v1.31.1 (entware package)

To demonstrate this bug, create a file script.sh with this contents:

#!/bin/sh
for ARG in $@ ; do echo $ARG ; done

Execute it like this:

./script.sh arg0 "arg1a arg1b" 'arg2a arg2b'

Expected output:

arg0
arg1a arg1b
arg2a arg2b

Real ouput:

arg0
arg1a
arg1b
arg2a
arg2b

See this standard:
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02
From what I understand, field splitting should not occur inside double quotes.
Comment 1 Ron Yorston 2020-04-16 11:13:16 UTC
Shouldn't the $@ in your script be in double quotes to get the expected result?
Comment 2 Marius 2020-04-16 16:31:27 UTC
Yes, it works, but I don't understand. Can you explain?

In my view, inside "script.sh 1 2 3", $@ expands into 3 elements:
1 2 3
while "$@" expands inside the quotes creating just one element:
"1 2 3"

So, after it's expanded,
for i in 1 2 3 ; do echo $i ; done
outputs:
1
2
3

and
for i in "1 2 3" ; do echo $i ; done
outputs:
1 2 3
Comment 3 Ron Yorston 2020-04-17 08:07:29 UTC
As described in the POSIX document you referenced $@ is a special case when it's within double quotes (in certain defined circumstances).  Unlike other quoted expansions it normally *doesn't* expand to a single string.

The bash documentation says of this case:

   That is, "$@" is equivalent to "$1" "$2" ...
Comment 4 Marius 2020-04-22 17:59:24 UTC
My mistake.