How to find executable filetypes?
Solution 1
Later edit: only this one does what jan needs: thank you huygens;
find . -exec file {} \; | grep -i elf
Solution 2
Alternate solution not using file
and readelf
, for those on limited (e.g. embedded) systems:
find $WHERE -type f -exec hexdump -n 4 -e '4/1 "%2x" " {}\n"' {} \; | grep ^7f454c46
Basically, we output first four bytes with hexdump
and use them as a signature. We can then grep all the files of type ELF using its signature 7f454c46
.
Or, since 7f
is the delete character, and 45
, 4c
, 46
bytes are E
, L
, F
characters respectively, we could also use:
find $WHERE -type f -exec hexdump -n 4 -e '4/1 "%1_u" " {}\n"' {} \; | grep ^delELF
Also, you can use head
instead of hexdump
in this case:
find $WHERE -type f -exec head -c 4 {} \; -exec echo " {}" \; | grep ^.ELF
Solution 3
Like others, I want to answer too. My answer is based on using the find
utility too, but I have an idea, which is differ against other answers. It grounded on that fact, that the -exec
can be used as the search criteria too. Now, having this thing in mind, we can refactor all of the previous proposals to this one:
find /path -type f -exec sh -c "file {} | grep -Pi ': elf (32|64)-bit' > /dev/null" \; -print
I.e. we have moved the grep
into the -exec
.
What does this give to us, you may ask? We can use the flexibility of the -print
and others of the find
utility. For example, we can format an output on our taste, or use the -print0
and redirect an output to some script etc.
Solution 4
Take a look on -executable
flag of find
.
Solution 5
I think this answers the original question if their intent was to find binary executable files by ensuring each match has an elf header.
It sort of pre-processes files based on type -executable
then runs the results through a separate shell that invokes readelf -l
which pipes to grep which silently matches on headers that are explicitly executable
. Anything that passes this test is passed to printf
for the output.
The pwd
bit outputs the full path.
find `pwd` -type f -executable -exec sh -c 'readelf -l "$1" 2>/dev/null | grep -qio 'executable' && printf "$1\n"' -- {} \;
Related videos on Youtube
JohnnyFromBF
Updated on September 18, 2022Comments
-
JohnnyFromBF over 1 year
I want to find file types that are executable from the kernel's point of view. As far as I know all the executable files on Linux are ELF files. Thus I tried the following:
find * | file | grep ELF
However that doesn't work; does anybody have other ideas?
-
JohnnyFromBF almost 12 yearsThat's not quite what I want, I don't want files that are tagged as executable files but I want to find ELF files, files that are recognized as executable by the kernel.
-
JohnnyFromBF almost 12 years
find . -exec file {} \; | grep -i elf
is what I was looking for, thanks! -
Huygens almost 12 yearsThe flag executable match permissions (so directories too), see the man page:
Matches files which are executable and directories which are searchable (in a file name resolution sense).
-
Huygens almost 12 yearsI think your first command doesn't work. It is searching for files with a name like "*elf *" (without taking into account the case). You want to grep the output just likeyou did in the second proposal.
-
Waqas almost 12 years@huygens I tested it before I posted and it works. touch elf 1elf 1ELF2 elf2</code> ; my command will find all the elf related files;
-
Waqas almost 12 years@huygens I tested it before I posted and it works. touch elf 1elf 1ELF2 elf2 ; my command will find all the elf related files (just like the grep); you got that error because you have copy pasted it (i think) and it has a blank space not needed, in the " " . but if I write "asteriskELFasterisk" in <code>, the html eats my asterisks!!!
-
Waqas almost 12 years@huygens : you are write, my mistake. I did not understand well what ian needed, at first.
-
Huygens almost 12 yearsActually my first answer is not fully correct, as some binary executable files are detected by
file -i
as application/x-sharedlib and not application/x-executable. -
user unknown almost 12 years@Huygens: So directories are files (everything is a file on Unix), but to exclude them, just use
find -type f -executable
. -
user unknown almost 12 years@Ian: But Shellscripts are executable by the kernel. Executable flag + appropriate shebang means executable file. Or flag + binary-elf, or flag + a.out, or flag + binfmt-patch.
-
Huygens almost 12 years@userunknown shell script aren't executable by the kernel. You need to run a shell and have the interpreter to execute them. As I understood Ian question, he is looking only for binary executable files. Thus
find -type f -executable
would not be correct as shell script would be reported. In addition if a binary does not have the x permission, this command would not detect it. Either it is wanted or not, both cases have different purpose. -
user unknown almost 12 years@Huygens: No, you can execute shell scripts with exec-calls, see: en.wikipedia.org/wiki/Shebang_%28Unix%29 . If there is a shebang, only the rest of the script is executed by the interpreter. Since 1980.
-
Huygens almost 12 years@userunknown interesting, didn't know that.
-
user2071406 about 10 yearsThe binaries I sampled from my Mac are
application/octet-stream; charset=binary
, according to both the Mac'sfile
and thefile
on my Debian box. (Speaking of OS X, thefile
it includes uses-I
instead of-i
. Both accept--mime
, though.) -
Anthon almost 9 yearsDoesn't work on all files/paths
-
John McGehee almost 8 yearsThis will find files that contain
"elf"
in their file name. I found that grepping for" elf "
was good enough for my application, but in the most general case a file named"this is not elf .txt"
would give a false positive. -
Jason Stewart over 2 yearsThe
grep
command could use the--text
flag. Without it, some file headers have characters that will putgrep
into binary mode--which will suppress all further matches with thegrep: (standard input): binary file matches
message. -
Adam Badura about 2 yearsHow about using
$'\x7FELF'
for the exact string to match?