53

If I use find command like this:

find /mydir/mysubdir -executable -type f

all executable files are listed (excluding directories), and including executable script file (like script.sh, etc). What I want to do is list only binary executable files.

1
  • 1
    Please change the subject to include the word 'binary', which is key to answering your question. Sep 2, 2010 at 3:43

4 Answers 4

49

You might try the file utility. According to the manpage:

The magic tests are used to check for files with data in particular fixed formats. The canonical example of this is a binary executable (compiled program) a.out file, whose format is defined in , and possibly in the standard include directory.

You might have to play around with the regular expression but something like:

$ find -type f -executable -exec file -i '{}' \; | grep 'x-executable; charset=binary'

file has lots of options, so you might want to take a closer look at the man page. I used the first option I found that seemed to output easily-to-grep output.

3
  • 17
    I'd say use find -type f -executable -exec sh -c "file -i '{}' | grep -q 'x-executable; charset=binary'" \; -print. It will only give you files (and thus can be passed to the next command he wants to run)
    – Gert
    Sep 2, 2010 at 6:56
  • serverfault.com/a/584595/211551 solution finds files that are NOT marked executable but are executable. Jun 13, 2017 at 6:14
  • On OS X, you can install GNU find with brew install findutils or sudo port install findutils and then you can run an invocation like this to a similar effect: gfind . -type f -executable -exec file '{}' \; | grep -i execut
    – GDP2
    Mar 26, 2018 at 4:49
10

Here's a way to exclude scripts, i.e., files whose first two characters are #!:

find -type f -executable -exec sh -c 'test "$(head -c 2 "$1")" != "#!"' sh {} \; -print

For some kinds of files, it's not clear whether you want them classified as scripts or binary, for example bytecode files. Depending on how things are set up, these may or may not start with #!. If these matter to you, you'll have to make the inner shell script more complex. For example, here's how you might include ELF binaries and Mono executables and Objective Caml bytecode programs but not other kinds of executables like shell scripts or perl scripts or JVM bytecode programs:

find -type f -executable -exec sh -c '
    case "$(head -n 1 "$1")" in
       ?ELF*) exit 0;;
       MZ*) exit 0;;
       #!*/ocamlrun*) exit 0;;
    esac
    exit 1
' sh {} \; -print
3
  • What is the reason for passing sh as first parameter to the sh -c command? The primary -exec sh -c 'test "$(head -c2 "$0")" != "#!"' {} \; seems to work equally well and is easier to grasp.
    – tbussmann
    Jul 21, 2021 at 16:34
  • 1
    @tbussmann sh is the value of $0. I've found that when I use $0 in sh -c (which I do more often than not), people complain that $0 should be reserved for the command name, more often than people complain that $0 should be used in this scenario (in fact I think you're the first to complain in this direction). Jul 21, 2021 at 17:01
  • @gilles-so-stop-being-evil: Thanks for your kind explanation. The man page is quite clear on this: "If there are arguments after the string, they are assigned to the positional parameters, starting with $0." But I understand why you are trying to avoid $0 by filling in a dummy value.
    – tbussmann
    Jul 21, 2021 at 17:52
2

Just in case you find yourself on a system with a downlevel find (there are still, as I write, a lotta science clusters running RHEL5!) without the rights to update: instead of

find /mypath/ -executable -type f

in the above excellent answers, you can do, e.g.,

find /mypath/h -type f -perm -u+x

which searches on permission bits. Unfortunately the above only finds files for which the user has executable, but that usually works for me.

1
  • 1
    This would still find executable scripts, not only binaries.
    – Kusalananda
    Jun 13, 2018 at 13:03
0

I coded a tool, called blobs, that does that.

The other methods miss some files.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.