In my answer here, I used the construct:
n=$1 shift
Reading Token Recognition spec, I understand that the shell will parse that line into two parts - the variable assignment n=$1
and the builtin command shift
.
But the comments on my answer state that n=$1 shift
does fail in some shells.
I spawned a quick check:
$ for shell in /bin/*[^c]sh; do
printf '=%-17s=\n' "$shell"
"$shell" -c 'a=$1 shift; echo "$a"' "$shell" 1
done
=/bin/ash =
1
=/bin/bash =
=/bin/dash =
1
=/bin/heirloom-sh =
1
=/bin/ksh =
1
=/bin/lksh =
1
=/bin/mksh =
1
=/bin/pdksh =
1
=/bin/posh =
1
=/bin/schily-osh =
1
=/bin/schily-sh =
1
=/bin/yash =
1
=/bin/zsh =
All shells, except bash
and zsh
, worked. But bash
in posix
mode and zsh
in sh
emulation do work, too:
$ ARGV0=sh bash -c 'a=$1 shift; echo "$a"' sh 1
1
$ ARGV0=sh zsh -c 'a=$1 shift; echo "$a"' sh 1
1
Using var=value; shift
worked in all shells.
So, are those constructs the same in POSIX-compliant shells?
shift
might be a special case. Try another builtin ega=$1 let x=99;...
, or a real command. (I remember many years ago having to go through all my scripts putting;
beforeshift
when I first moved to bash). – meuh Mar 06 '16 at 19:17