Why an empty (executable) file is generally true in Unix
Among a certain segment of Unix people, a famous bit of trivia is
/bin/true used to be an empty file until people complicated
it (via, which reminded
me of this). However, you might wonder why an empty executable file
would be true. This more or less follows from a variety of standard
and traditional behaviors, like this:
- If a shell script ends without an explicit '
exit <status>' command, its exit status is the exit status of the last command run in the script. (This sometimes leads people to put '
exit 0' and the end of scripts to force a successful exit even if the immediately previous command failed.)
- If a shell script doesn't run any commands, this 'last command'
behavior is extended to have its exit status be 0; after all, no
commands have failed.
- it's traditional Unix behavior that shell scripts without a #! line are still passed directly to the (Bourne) shell to run. This dates back to V7 Unix (or earlier) and is part of the complicated and surprising history of comments in the Bourne shell.
When you line all of these up, an empty executable file is interpreted as an empty (Bourne) shell script, which has exit status 0. And this is how an empty (executable) file is true.
(Empty files that aren't executable are generally going to be an error; Bash on Linux reports 'permission denied', for example.)
Today, all of this behavior is required by the Unix specification. One part of it is in the section on the exec*() functions. This specifically requires the behavior of passing 'shell scripts' to the shell:
[...] In the cases where the other members of the exec family of functions would fail and set
errnoto [ENOEXEC], the
execvp()functions shall execute a command interpreter and the environment of the executed command shall be as if the process invoked the sh utility using
execl()as follows: [...]
There's similar language in the description of how the POSIX shell
is to execute commands
(in 1.e.b and 2). The POSIX
sh manual page
further requires that the shell exit with a 0 status if the script
to be executed consisted only of zero or more blank lines and
A shell that doesn't claim to be POSIX compatible doesn't have to have this 'pass files to sh' behavior, but if it lacks it, some number of random programs will probably fail to get run some of the time. On the whole I suspect that most alternate shell authors implement the behavior for compatibility.
(It's both interesting and reassuring how many of the odd historical little corners of Unix have been chased down and carefully standardized by POSIX.)