Common issues faced with exec
ing an executable on Linux
This post's featured URL for sharing metadata is https://www.jvt.me/img/profile.jpg.
There are a number of somewhat esoteric errors you can hit when trying to execute another binary, and as I hit one today that took a bit of thinking, I decided to write it up as a form of blogumentation.
exec: {...} exec format error
- the executable you're trying to run is for a different CPU architecture
We see this, for instance, when trying to execute a binary:
% ./dmd
zsh: exec format error: ./dmd
In this case, it's not super clear what's going wrong, and what format
means in this case, as there's no information provided.
We can see that the permissions are correct:
% ls -al
-rwxr-xr-x 1 jamie jamie 26214552 Jul 28 20:06 ./dmd
But when we run it through file
we can see the cause more easily:
./dmd: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, stripped
# ^^^^^^^^^^^
Root cause: we're running an executable that was built for a different CPU architecture than we're currently running.
Note that we'll also see the same if we're running a binary that's compiled for a different Operating System.
I've hit this the most when I was working at Deliveroo, and we had a mix of folks on Intel and M1/M2 Macs, or were building Go binaries locally and then shipping them in a container that would then be run on an AMD64 Docker container host.
See also: Which OS and CPU architecture is this binary compiled for? and Transparently running binaries from any architecture in Linux with QEMU and binfmt_misc
not a directory
We see this, for instance, when trying to execute a shell script:
% ./a.sh
zsh: not a directory: ./a.sh
In this case, it's super unclear why there's a directory
being referenced.
We can see that the permissions are correct:
% ls -al
-rwxr-xr-x 1 jamie jamie 20 Jul 30 12:42 ./a.sh
And when we run file
, we can see it's a correctly formed shell script:
./a.sh: a bash script, ASCII text executable
If we look closer at the contents of the script, it may be clearer:
#!/usr/bin/env/bash
# ^
Root cause: we're referencing an executable as part of our Shebang that's not a valid binary.
To fix this:
-#!/usr/bin/env/bash
+#!/usr/bin/env bash