Reputation: 43
The GNU bash manual has the following passage while talking about shell parameters:
The
command
builtin does not prevent builtins that take assignment statements as arguments from expanding them as assignment statements; when not in POSIX mode, assignment builtins lose their assignment statement expansion properties when preceded by command.
I can't figure out what it's talking about, and I also can not manage to write a command that differs in behavior of assignment expressions between regular mode and posix mode for this reason.
Can anyone find an example of this difference?
Upvotes: 4
Views: 232
Reputation: 50795
Can anyone find an example of this difference?
Yes, here you go:
$ touch foo=bar
$
$ command declare foo=*
$ declare -p foo
declare -- foo="bar"
$
$ set -o posix
$ command declare foo=*
$ declare -p foo
declare -- foo="*"
In POSIX mode, foo=*
doesn't expand to foo=bar
; it stays verbatim because pathname expansion isn't performed on assignment statements.
But in normal mode it does; preceding declare
with command
causes foo=*
to be interpreted as a regular argument rather than an assignment statement; thus it undergoes pathname expansion.
And another one:
$ foo='x y=z'
$
$ command declare bar=$foo
$ declare -p bar y
declare -- bar="x"
declare -- y="z"
$
$ unset bar y
$ set -o posix
$ command declare bar=$foo
$ declare -p bar y
declare -- bar="x y=z"
bash: declare: y: not found
In this case, the difference is that $foo
undergoes word splitting (as it's unquoted) in normal mode, resulting in two separate arguments, bar=x
and y=z
. But in POSIX mode the space is retained, and the result of expansion is not split. Hence bar='x y=z'
.
Upvotes: 9