For example, if I do
[OP@localhost executable]$ cat garbage
lalala
trololol
[OP@localhost executable]$ chmod +x garbage
[OP@localhost executable]$ ./garbage
./garbage: line 1: lalala: command not found
./garbage: line 2: trololol: command not found
Bash seems to be trying to interpret this "executable" as a script. However, there are two instances where this clearly does not happen: when the file begins with a #!
, and ELF files. Are there any more? Is there a comprehensive documentation of this somewhere?
Best Answer
Expanding on my previous comment on another answer, the kernel contains seven binary loaders (look for files starting with
binfmt_
there, or read thebinfmt
-specificKconfig
):a.out
(which is currently on a stay of execution);em86
(on Alpha);binfmt_misc
(see also What kinds of executable formats do the files under /proc/sys/fs/binfmt_misc/ allow?).These are what determine the types of executable files that the kernel can execute.
binfmt_misc
in particular allows many other binaries to be handled by the kernel (at least, from the perspective of the process calling one of theexec
functions).However this doesn’t cover the whole story, since the C library and shells themselves are also involved. POSIX now requires that the
execlp
andexecvp
functions, when they encounter an executable which the kernel can’t run, try running it using a shell; see the rationale here for details.The way all this interacts to provide the behaviour you’re seeing is detailed in What exactly happens when I execute a file in my shell? and Which shell interpreter runs a script with no shebang?