As mentioned in the title, the set -o posix
option does not appear to be working in GNU/Linux bash 5.0.17 (I'm not sure it's specifically related to WSL2 Ubuntu 20.04 or anything, but noted it in case it is working for others on their machines).
I can turn it on and off:
$ set -o |grep posix
posix off
$ set -o posix
$ set -o |grep posix
posix on
$ set -o posix
$ set -o |grep posix
posix off
$ set -o posix
$ set -o |grep posix
posix on
but, for example, when on I am able to do the following
$ set -o posix
$ set -o |grep posix
posix on
$ type cd
cd is a shell builtin
$ cd /
$ ls
bin dev home lib lib64 lost+found mnt proc run snap sys usr
boot etc init lib32 libx32 media opt root sbin srv tmp var
$ cd() { :; }
$ type cd
cd is a function
cd ()
{
:
}
$ cd ~
$ ls
bin dev home lib lib64 lost+found mnt proc run snap sys usr
boot etc init lib32 libx32 media opt root sbin srv tmp var
$ unset -f cd
$ cd ~
$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos
I am able to override all special builtins (including builtin
and type
!). Also, I am not root, but just in my user account. Does anyone know what I am doing wrong?
UPDATE:
@Shawn, @oguzismail, and @Dan all give the correct answer below: cd
is a regular builtin. I wanted to add some clarification as I think it will be important for learners like me:
@oguzismail correctly points to the section of Classic Shell Scripting that explains that cd
is a regular built-in:
For this reason, you can write a function named cd, and the shell will find your function first, since cd is a regular built-in
My confusion came from the statement in the summary:
Built-in commands exist either because they change the shell’s internal state and must be built-in (such as cd), or for efficiency (such as test).
Here, cd
is a builtin, but as the author states previously, it is a regular builtin. It has to be a command built into the shell because the command changes the internal state of the shell (i.e. it changes the current/present working directory of the shell), but it can be either a regular or special builtin. As @Dan mentions, the POSIX IEEE Std 1003.1-2017 standard, Section 2.14 defines it as a regular builtin. (For at least one reason why, Section 7.9 of Classic Shell Scripting shows that doing so permits the programmer to customize its behavior.)
Be Warned Though! (NB = Nota Bene): If you do choose to overwrite cd
with a user-defined function, use command cd
within the function definition where you want to actually change directories. The function command
skips looking for functions in the POSIX-defined search order of special built-ins --> functions --> regular built-ins --> external commands on $PATH
. Otherwise, if you use cd
within your user-defined function cd
, you will most likely end up with an infinite recursion loop. (Classic Shell Scripting also covers this point.)
set -o posix
works fine:
$ set -o posix
$ set () { :; }
bash: `set': is a special builtin
cd
is not a special built in, nor is builtin
or type
.
The list of "special builtins" is clearly defined in the posix specification.
A "special built-in" is distinct from any other command which a shell may or may not implement as a built-in.