Bug 12776 - $@ containing quoted string is split into separate arguments
Summary: $@ containing quoted string is split into separate arguments
Status: RESOLVED INVALID
Alias: None
Product: Busybox
Classification: Unclassified
Component: Standard Compliance (show other bugs)
Version: 1.31.x
Hardware: Other Linux
: P5 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-04-16 10:55 UTC by Marius
Modified: 2020-04-22 17:59 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
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.