Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is bash doing "$@" expansion incorrectly inside ${var+...}?

I currently get 2 opinions by 3 shells:

$ bash -c 'set bar; set foo${1+ "$@"}; echo "$# $*"'
1 foobar

$ ash -c 'set bar; set foo${1+ "$@"}; echo "$# $*"'
2 foo bar

$ dash -c 'set bar; set foo${1+ "$@"}; echo "$# $*"'
2 foo bar

Or did I overlook some POSIX definition which renders my example as implementation-defined behavior?

Note that only "$@" seems to trigger differences. The following works the same for all 3 shells:

$ bash -c 'set bar; set foo${1+ $*}; echo "$# $*"'
2 foo bar

$ ash -c 'set bar; set foo${1+ $*}; echo "$# $*"'
2 foo bar

$ dash -c 'set bar; set foo${1+ $*}; echo "$# $*"'
2 foo bar

Unfortunately, $* is not quite the same as "$@" if the arguments should contain whitespace.

BTW, I am using Bash version 4.4.12(1)-release.

like image 904
Guenther Brunthaler Avatar asked Aug 27 '18 21:08

Guenther Brunthaler


1 Answers

I tend not to trust spaces inside unquoted parameter expansion. I can't explain why it doesn't work, but I can give you a solution that does: move the space outside the parameter expansion. The set command doesn't mind trailing white space.

$ bash -c 'set bar; set foo ${1+"$@"}; echo "$# $*"'   # 5.0.2(1)
2 foo bar

$ dash -c 'set bar; set foo ${1+"$@"}; echo "$# $*"'   # 0.5.10.2
2 foo bar

$ ash  -c 'set bar; set foo ${1+"$@"}; echo "$# $*"'   # /bin/sh on FreeBSD 7.3
2 foo bar

$ ksh  -c 'set bar; set foo ${1+"$@"}; echo "$# $*"'   # 93u+ 2012-08-01
2 foo bar

$ zsh  -c 'set bar; set foo ${1+"$@"}; echo "$# $*"'   # 5.7
2 foo bar

(I ran everything on the latest Debian Testing except ash)

like image 193
Adam Katz Avatar answered Sep 18 '22 09:09

Adam Katz