Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

bash

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?

like image 671
user2304936 Avatar asked Dec 31 '22 04:12

user2304936


1 Answers

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'.

like image 139
oguz ismail Avatar answered Jan 22 '23 12:01

oguz ismail