Bourne | Ash |  #!  | find | ARG_MAX | Shells | portability | permissions | UUOC | ancient | - | ../Various | HOME
"$@" | echo/printf | set -e | test | tty defs | tty chars | $() vs ) | IFS | using siginfo | nanosleep | line charset | locale


What does ${1+"$@"} mean,

...and where is it necessary?

2010-08-29 (see recent changes)


It's a workaround for older releases from of the traditional Bourne shell: they parse "$@" in an non-intuitive way if no arguments were supplied.
As all modern bourne compatible shells use the intuitive convention, this page concentrates on the family of traditional Bourne shells.
Among these, the modern and intuitive behaviour was introduced with the SVR3 bourne shell.

An example

Here is a shell, where this workaround is necessary:

With the following script,

	$ cat args.sh
	for i in "$@"; do
	    echo arg: \"$i\"
	done
you get output as expected if you provide at least one argument:
	$ sh args.sh 1 2
	arg: "1"
	arg: "2"
However, without arguments, you still get (empty) output, instead of no output at all:
	$ sh args.sh
	arg: ""

Why is this relevant?

Keep in mind, that "$@" is most frequently used for passing on arguments, or for iterating over them in a loop, like above.
Thus a mechanism for collapsing the argument list to nothing--and not to the empty argument--really makes sense.

How does it work?

The ${1+"$@"} syntax first tests if $1 is set, that is, if there is an argument at all.
If so, then this expression is replaced with the whole "$@" argument list.
If not, then it collapes to nothing instead of an empty argument.

Another, historic problem

Even with the above workaround, early shells before SVR2 (V7, BSDs, SysIII and SVR1) discard empty arguments in the argument list.

	$ sh ./args.sh 1 '' 2
	arg: "1"
	arg: "2"

Portability

Otherwise, ${1+"$@"} is robust and portable. With one exception:

zsh until release 4.3.0, in sh emulation mode (when the option shwordsplit is set), does word splitting on the resulting arguments.

	$ sh ./args.sh '1 2'
	arg: "1"
	arg: "2"

The old behaviour is not a bug in the very sense, but an unintuitive de-facto behaviour of those shells. It was not properly specified, yet.


An alternative

You might just loop youself over the arguments:

    for i
    do
	echo "$i"
    done 

or, interestingly enough without semicolon,

    for i do
	echo "$i"
    done 

Although this is not documented for the Version 7 Bourne shell (and its variants on early BSDs), this works on these systems, too.
(Picked up from the german lang usenet posting <3BE2D2D3.I715123W@bigfoot.de> from Gunnar Ritter; and I could confirm this on all the flavours).
(Embedded questionmarks or blanks show up, because Google had problems with quoted printable that time.)

In contrast to ${1+"$@"}, these variants even work correctly in the pre-SVR2 variants if there are empty arguments in the list (pointed out by Stéphane Chazelas and I can confirm it).
However, for passing on the arguments to another program (instead of iterating over them) ${1+"$@"} (or "$@") are certainly the only solution.


Which Bourne shells need the above workaround?

These shells behave the old way and need ${1+"$@"}:

In contrast, these Bourne shell variants behave the modern way:


<http://www.in-ulm.de/~mascheck/various/bourne_args/>

Sven Mascheck