8

Brace Expansion, eg {a,b,c} is not defined by POSIX. I would like to run my shell in POSIX mode. With Debian this is simple enough:

$ bash -c 'echo {a,b,c}'
a b c

$ sh -c 'echo {a,b,c}'
{a,b,c}

However Fedora behaves differently:

$ bash -c 'echo {a,b,c}'
a b c

$ sh -c 'echo {a,b,c}'
a b c

I tried using --posix option, but it has no effect:

$ sh --posix -c 'echo {a,b,c}'
a b c

Can Bash be forced to operate in POSIX mode?

3 Answers 3

5

Bash can be told to disable brace expansion with set +B, which is the inverse of set -B:

-B The shell will perform brace expansion (see Brace Expansion). This option is on by default.

You can also provide this on the command line when launching the shell:

$ bash +B -c 'echo {a,b,c}'
{a,b,c}

You can combine this with the --posix or set -o posix options to get closer to fully-POSIX behaviour. You also need to enable shopt -s xpg_echo at least.

There will be other corners as well — many of the extensions are quite deeply-ingrained — and I don't think it's possible to get Bash to support only the behaviour that is actually mandated by POSIX. Even dash doesn't manage that.

However, you may find dash (the default /bin/sh on Debian) more helpful if you're aiming to avoid extended behaviours, although it supports some extensions as well. There is also BusyBox's ash applet, which also has some extensions, but many can be disabled statically.

1

According to the Bash Reference Manual (http://www.gnu.org/software/bash/manual/html_node/Bash-POSIX-Mode.html), the --posix flag "will cause Bash to conform more closely to the POSIX standard". It seems full POSIX compliance isn't an option.

As for the difference in behavior, I believe you'll find /bin/sh is a symlink to /bin/bash on Fedora. Debian probably has a non-bash implementation for /bin/sh.

2
  • 1
    On debian /bin/sh usually is dash
    – Anthon
    Jan 30, 2016 at 21:45
  • Small addition to the above; (bash manual) : If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.
    – MAQ
    Jan 30, 2016 at 22:15
0

In default Debian, sh is a link to dash (not bash). Dash fits more closely the POSIX behavior for "Brace Expansion".

Bash has this documented difference with historical sh (from man bash):

Brace expansion introduces a slight incompatibility with historical versions of sh. sh does not treat opening or closing braces specially when they appear as part of a word, and preserves them in the output. Bash removes braces from words as a consequence of brace expansion. For example, a word entered to sh as file{1,2} appears identically in the output. The same word is output as file1 file2 after expansion by bash. If strict compatibility with sh is desired, start bash with the +B option or disable brace expansion with the +B option to the set command.

Either of this work:

bash +B -c 'echo {a,b,c}'
bash -c 'set +B; echo {a,b,c}'

And, if you still need a more POSIXly bash:

bash --posix +B -c 'echo {a,b,c}'
bash --posix -c 'set +B; echo {a,b,c}'

As changing the default shell for /bin/sh has many system wide consequences, I do not recommend you to change /bin/sh to dash.

However, it is usual that $HOME/bin/ (or a.k.a ~/bin/) is set ahead of /bin/ in the PATH. So, you could copy a dash executable to your user ~/bin/sh (or even a symbolic or real link) and dash will work as the default sh for that user.

Sometimes the inclusion of ~/bin/ as user executable programs is done in .profile:

[ -d "${HOME}/bin" ] && export PATH="${HOME}/bin:$PATH"

which is sourced by (almost any shell) bash on the first login (at server X start time for the user) and from then on it exists as an environment value.

If that exists, all you have to do is create the /home/$USER/bin directory.
Of course, you need to login back again or source ~/.profile once.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .