PDA

View Full Version : Baffled by Bash/Dash brace expansion cleverness



ofnuts
October 23rd, 2011, 02:20 PM
While tracking what really gets executed when I invoke the native2ascii command in the IBM JDK, I stumbled upon a very short script that contains:


#! /bin/sh
exec /usr/lib/j2sdk1.6-ibm/bin/native2ascii ${1+"$@"}
And I can't figure out what this ${1+"$@"} is trying to achieve (I would have use a plain $@), since I don't see this as a valid brace expansion... but the plot thickness when one notices that the script is run by /bin/sh which is dash and not bash, so brace expansion would not be supported anyway?

If that makes any difference, /usr/lib/j2sdk1.6-ibm/bin/native2ascii isn't a script (ELF 32-bit LSB executable)

Vaphell
October 23rd, 2011, 04:09 PM
${x+y} seems to work in sh just fine.
"script"

echo ${1+"x"}

$ sh params.sh

$ sh params.sh abc def
x


I also don't get why would anyone use that. ${1+"$@"} tests if $1 is set and if true, uses the alternate value of "$@" instead which i think is the same as using $@ in the first place.

StephenF
October 23rd, 2011, 05:15 PM
I also don't get why would anyone use that. ${1+"$@"} tests if $1 is set and if true, uses the alternate value of "$@" instead which i think is the same as using $@ in the first place.
ls -l -h

is not

ls "-l -h"

and

ls

is not

ls ""

Vaphell
October 23rd, 2011, 05:43 PM
that's true but it doesn't make any difference here as far as i can tell

i wrote a script that passes params with both methods to another script that prints the params and their number

$ sh params.sh
${1+"$@"}: / 0
"$@": / 0
$ sh params.sh ""
${1+"$@"}: // 1
"$@": // 1
$ sh params.sh "" "" ""
${1+"$@"}: / / // 3
"$@": / / // 3
$ sh params.sh "a" "" ""
${1+"$@"}: a / / // 3
"$@": a / / // 3

StephenF
October 23rd, 2011, 08:52 PM
I did the same and got the same results. I can only imagine that this is compatibility code and some other shell out there does things differently.

gsmanners
October 23rd, 2011, 08:55 PM
Yes, nothing like being clever rather than doing a version check explicitly.

Arndt
October 23rd, 2011, 09:10 PM
Yes, nothing like being clever rather than doing a version check explicitly.

What would that version test look like?

gsmanners
October 23rd, 2011, 09:42 PM
What would that version test look like?

Darned if I know, but I tell you one thing: I'd write in Python or C -- not Bash script.

ofnuts
October 24th, 2011, 05:18 PM
Glad to see I'm not the only one baffled :)

sisco311
October 25th, 2011, 03:33 PM
${1+"$@"} is a parameter expansion, NOT a brace expansion.

BASH:

man bash | less +/"^ +Parameter Expansion"

DASH:

man bash | less +/"^ +Parameter Expansion"

POSIX:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02

Also check out BashFAQ 83 (link in my signature).

gsmanners
October 25th, 2011, 04:54 PM
Oh, I see. This is a case of "cleverness" on the part of Bash, not the coders.

Arndt
October 25th, 2011, 08:04 PM
Oh, I see. This is a case of "cleverness" on the part of Bash, not the coders.

I think this construction predates bash. Some implementations of sh handled arguments somewhat differently than others, and someone came up with this trickiness to be portable. I've never really investigated what it does and why.