user2304936
user2304936

Reputation: 43

Bash assignment statement expansion in POSIX vs. non-POSIX mode

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

Answers (1)

oguz ismail
oguz ismail

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

Related Questions