What is POSIX-compatible mode in Linux?
Solution 1:
This is not a Linux thing, it's a bash thing. Bash is just one of many shells. Bash is the "Bourne again shell" and was released as a replacement of the original Bourne Shell, sh
.
POSIX is a set of standards defining how POSIX-compliant systems should work. The POSIX shell standard can be found here. Bash has many features not present in sh
and is not actually a POSIX compliant shell.
This is why the --posix
option is provided. As explained in man bash
(emphasis mine):
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. When invoked as an interactive login shell, or a non-interactive shell with the --login option, it first attempts to read and execute commands from /etc/profile and ~/.profile, in that order. The --noprofile option may be used to inhibit this behavior. When invoked as an interactive shell with the name sh, bash looks for the variable ENV, expands its value if it is defined, and uses the expanded value as the name of a file to read and execute. Since a shell invoked as sh does not attempt to read and execute commands from any other startup files, the --rcfile option has no effect. A non-interactive shell invoked with the name sh does not attempt to read any other startup files. When invoked as sh, bash enters posix mode after the startup files are read.
When bash is started in posix mode, as with the --posix command line option, it follows the POSIX standard for startup files. In this mode, interactive shells expand the ENV variable and commands are read and executed from the file whose name is the expanded value. No other startup files are read.
This means that if you run sh
, or bash --posix
, to start an interactive shell, your ~/.bahsrc
file is ignored and, instead, the file saved as $ENV
(if any) is read. To illustrate, I have added echo "read .bashrc"
to my ~/.bashrc
:
$ bash
read .bashrc ## message was printed, ~/.bashrc was read
$ sh
sh-4.3$ ## no message printed, ~/.bashrc was not read
If I now set $ENV
:
$ export ENV="~/.bashrc"
$ sh
read .bashrc
IMPORTANT NOTE: Ubuntu has chosen to make /bin/sh
a synlink to /bin/dash
. Dash is yet another shell and is actually a POSIX-compliant one. This means that in order to observe the behavior I described above, you need to use a different sh
1. On Ubuntu, you need to create a file called sh
that is a symlink to /bin/bash
:
$ ln -s /bin/bash ~/sh
You now have a file called sh
in your home directory. Use that to demonstrate the differences I explained above:
$ ls -l ~/sh
lrwxrwxrwx 1 terdon terdon 9 May 2 14:03 /home/terdon/sh -> /bin/bash
$ ~/sh
read .bashrc
1Actually, the behavior will look as though it's the same, ~/.bashrc
will be ignored, but that's just because dash
is not bash
and has no business reading the bash-specific ~/.bashrc
anyway. However, dash
also ignores $ENV
so you need to use the link to /bin/bash
to see that.