I accidentally unset $PATH. Why did `echo` still work?
So there I was. Trying to append to $PATH
. Uh oh! I accidentally unset $PATH
! For whatever reason I ran
$ ls
bash: ls: command not found
To be expected. Then I ran
$ echo $PATH
$PATH:/home/jon/.local/bin
Is echo
some sort of special case? Why isn't it on $PATH
? Is it built in to bash?
Solution 1:
echo
is a bash builtin. It does not use the $PATH
to find the echo
program, instead bash has it's own version of echo
which is used instead of the echo
program located in your $PATH
read more here: Bash Builtins (Bash Reference Manual)
Solution 2:
In addition to what Minijack mentioned, you can check what a command is by using the type
builtin.
$ type echo
echo is a shell builtin
On the other hand, which
can be used to check for executables specifically. Once you unset $PATH, you'll get something like
$ which echo
/usr/bin/which: no echo in ((null))
Whereas with your path set you get
/usr/bin/echo
You can check man builtins
for list and desription of various builtins. For example, [
and test
are also builtins.
EDIT: which
works for me even without PATH because of an alias that uses an absolute path
Solution 3:
The model employed by the Single Unix Specification (a.k.a. IEEE 1003.1) is that whether a command is built into a shell is a mere optimization, and the behaviour (if invoked in a conformant manner) should be the same for a built-in version of a command as for an external version. (This is regular built-ins, that is. Special built-ins are another matter.) In particular, if the command is not found as an external in a PATH
search, the built-in version is not to be executed.
This is indeed what happens with one shell. You'll find that the Watanabe shell conforms to the SUS. In its posixly-correct
mode, if echo
is not on the path, the built-in echo
command in the Watanabe shell will not be executed.
But the 93 Korn, Debian Almquist, Z, and Bourne Again shells in their most conformant modes still all execute built-ins even if there is no corresponding executable on PATH
. That is what is happening here for you. The Bourne Again shell has a built-in echo
command, and several others besides. It is executing that, even though it has not found an external echo
command in a PATH
search.
(Note that there are quite a few ways to invoke echo
in a non-conformant manner, or at least in a manner where the result is unspecified: Using -n
; using a backslash in any argument; using -e
; using other things expecting them to be command options or end of options markers. These not only reveal whether it is a built-in echo
, but even to an extent reveal what shell is in use. Fortunately, you did not hit any of them. ☺)
Further reading
- https://unix.stackexchange.com/a/496377/5132
- https://unix.stackexchange.com/a/496291/5132
- "Command search and execution". Shell Command Language. IEEE Std 1003.1-2017. The Open Group.
-
echo
. Utilities. IEEE Std 1003.1-2017. The Open Group. - "Why is
printf
better thanecho
?"