How can I find only the executable files under a certain directory in Linux?

277,153

Solution 1

Checking for executable files can be done with -perm (not recommended) or -executable (recommended, as it takes ACL into account). To use the -executable option:

find <dir> -executable

if you want to find only executable files and not searchable directories, combine with -type f:

find <dir> -executable -type f

Solution 2

Use the find's -perm option. This will find files in the current directory that are either executable by their owner, by group members or by others:

find . -perm /u=x,g=x,o=x

Edit:

I just found another option that is present at least in GNU find 4.4.0:

find . -executable

This should work even better because ACLs are also considered.

Solution 3

I know the question specifically mentions Linux, but since it's the first result on Google, I just wanted to add the answer I was looking for (for example if you are - like me at the moment - forced by your employer to use a non GNU/Linux system).

Tested on macOS 10.12.5

find . -perm +111 -type f

Solution 4

I have another approach, in case what you really want is just to do something with executable files--and not necessarily to actually force find to filter itself:

for i in `find -type f`; do [ -x $i ] && echo "$i is executable"; done

I prefer this because it doesn't rely on -executable which is platform specific; and it doesn't rely on -perm which is a bit arcane, a bit platform specific, and as written above requires the file to be executable for everyone (not just you).

The -type f is important because in *nix directories have to be executable to be traversable, and the more of the query is in the find command, the more memory efficient your command will be.

Anyhow, just offering another approach, since *nix is the land of a billion approaches.

Solution 5

A file marked executable need not be a executable or loadable file or object.

Here is what I use:

find ./ -type f -name "*" -not -name "*.o" -exec sh -c '
    case "$(head -n 1 "$1")" in
      ?ELF*) exit 0;;
      MZ*) exit 0;;
      #!*/ocamlrun*)exit0;;
    esac
exit 1
' sh {} \; -print
Share:
277,153

Related videos on Youtube

HaiYuan Zhang
Author by

HaiYuan Zhang

Updated on September 17, 2022

Comments

  • HaiYuan Zhang
    HaiYuan Zhang over 1 year

    How can I find only the executable files under a certain directory in Linux?

    • AjayKumarBasuthkar
      AjayKumarBasuthkar about 10 years
      Here is a kind of BASH script, it is not-bad is what I can say :) stackoverflow.com/a/20209457/2067125
    • Breakthrough
      Breakthrough over 9 years
      What about using the standard file command?
    • techfoobar
      techfoobar over 9 years
      For anyone wanting to do this on a Mac (tested on OS X 10.9.5): ls -l | egrep '^[^d]..x..x..x.*$' The above will list all executables (for all/user and group) in the current directory. Note: The -executable option does not work on a Mac hence the above workaround.
    • Slothworks
      Slothworks over 8 years
    • G-Man Says 'Reinstate Monica'
      G-Man Says 'Reinstate Monica' about 8 years
      @techfoobar: The question is ambiguous: Does it mean files that contain executable code, or does it mean files that have executable permission?  But even if we assume that executable permission is what is wanted (as the majority of the responses seem to), the question doesn't say world-executable.  Your solution will find files (and also fifos, sockets, symlinks, etc.) that have world execute permission, but not 750 (-rwxr-x---), which is still executable to some users.
  • Ben
    Ben over 14 years
    This will return files with the execute turned on only. A more thorough analysis would check for a shebang line or whether the file is binary
  • nerkn
    nerkn over 14 years
    a shebang doesn’t mean they’re executable. it tells us only which interpreter to use. and by linux definition “executable files” are files with the executable (x) bit set
  • innaM
    innaM over 14 years
    What version of find supports that type for -type? man find lists b, c, d, p, f, l, s and D on my system.
  • davr
    davr over 14 years
    Same here, my find doesn't have a -type x either.
  • davr
    davr over 14 years
    This only works on a newer version of find. The one that comes by default with CentOS gives the error find: invalid mode /u=x,g=x,o=x'`
  • innaM
    innaM over 14 years
    Then you should try the "-perm +" version which is now deprecated in GNU find: find . -perm +111"
  • Garik
    Garik over 14 years
    For some reason I always think that "-type x" will work too. I can only imagine it was available on some flavour of Unix I used once.
  • nerkn
    nerkn over 14 years
    @dave: glad to hear i’m not the only one :)
  • karthik
    karthik almost 14 years
    If you have an old version of find (probably before 4.3.8) which lacks -executable use find . -perm /u=x,g=x,o=x.
  • Good Person
    Good Person over 11 years
    -executable isn't at all portable and should be avoided
  • SSH This
    SSH This almost 11 years
    find: invalid predicate -executable' on RHEL
  • DerMike
    DerMike over 9 years
    What does this do?
  • AjayKumarBasuthkar
    AjayKumarBasuthkar over 9 years
    @DerMike, It is one of the ways to find executable in current directory, including .so files, even if a file is not marked executable it can discover.
  • DerMike
    DerMike over 9 years
    Well, I mean, how does it do that?
  • AjayKumarBasuthkar
    AjayKumarBasuthkar over 9 years
    It reads from the header of the file to discover, every binary file or script file has header.
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' about 8 years
    As far as I know, -name "*" has no effect on find — it normally finds all files that are not eliminated by tests.
  • Scott - Слава Україні
    Scott - Слава Україні about 8 years
    Seems like -perm /111 may be the most portable version.
  • Scott - Слава Україні
    Scott - Слава Україні about 8 years
    (0) Which do you prefer, arcane and correct or intuitive and flawed?  I prefer correct.  (1) innaM’s answer, featuring find -perm, finds files that have any execute permission bit set.  (2) By contrast, this answer finds only files for which the current user has execute permission.  Granted, that might be what the OP wants, but it’s unclear.  … (Cont’d)
  • Scott - Слава Україні
    Scott - Слава Україні about 8 years
    (Cont’d) …  (3) For clarity, you might want to change `…` to $(…) — see this, this, and this.  (4) But don’t do for i in $(find …); do …; it fails on filenames that contain space(s).  Instead, do find … -exec ….  (5) And, when you do work with shell variables, always quote them (in double quotes) unless you have a good reason not to, and you’re sure you know what you’re doing.
  • Mark McKenna
    Mark McKenna about 8 years
    @scott OK, I stand corrected :) I read the -perm argument as requiring all three, not one of them. Also, thank you for the input on protecting shell arguments, that's all stuff I wasn't aware of.
  • nonchip
    nonchip over 7 years
    @AjayKumarBasuthkar you are aware this is NOT an answer to the question? the question was how to find executable files (=those that can be executed, = those w/ +x). not how to find all ELF, EXE and whatever-ocamlrun-is files.
  • Devy
    Devy over 7 years
    @MarkMcKenna you have a typo in there: for i in find . -type f; do [ -x $i ] && echo "$i is executable"; done; you are missing the <dir> part, which I use a dot(.)
  • xenoid
    xenoid almost 7 years
    That won't work if the script contains non-ASCII characters. file reports the encoding, so a python script can be reported as a /usr/bin/python script, UTF-8 Unicode text executable. find ... | xargs file -b | grep -v '^ELF' could work better to spot the non-binaries.
  • José Tomás Tocino
    José Tomás Tocino almost 6 years
    Works in RHEL 5 too.
  • Oliver
    Oliver over 5 years
    This is the only variant I could get working on OS X 10.14, thx
  • Dan Bolser
    Dan Bolser about 5 years
    How about not executable? Seems like a good thing to add here...
  • nerkn
    nerkn about 5 years
    @DanBolser that's as simple as find -not -executable (optionally with -type f, depending on whether you want to only include files in the result)
  • Dan Bolser
    Dan Bolser about 5 years
    Thanks @knittl, worth editing the answer?
  • nerkn
    nerkn about 5 years
    @DanBolser the discussion probably takes longer than actually updating the answer, but I think the answer is complete as it stands now. The OP was specfically about finding files which are executable, not about excluding them. I expect people to read the find man page to some extent and they will find the basic -not operator there.
  • Dan Bolser
    Dan Bolser about 5 years
    I can't edit it. I've been using find for years, but -executeable and -not are both new to me (just saying ;-)
  • jmcarter9t
    jmcarter9t over 4 years
    Needed this while using a busybox build of find. -executable did not work. -perm +111 is perfect.
  • Torque
    Torque about 4 years
    @nonchip I strongly disagree. @OP did not ask what files were set to executable/+x, but what files were actually executable. The definition of what that means is left to the reader, but I would not consider portrait.png executable, even with a+x, and I would consider /usr/bin/grep an executable, even if it was accidentally changed to miss the x flag.
  • nonchip
    nonchip about 4 years
    @Torque but portrait.png can be executable by your logic, just get a Piet interpreter. and even if then executable means "can be run with ./" (which requires x) just configure binfmt_misc. also pretty sure the grammar "only the executable files" implies "only the files which are executable", not files that are of the few (of the many executable formats out there) you deemed worthy. that would be "only ELF files", "only programs" or similar. and you didn't find .app,.py, .lua, .sh, all executables (even usually with ./ from bash), unlike .so and .dll.
  • AjayKumarBasuthkar
    AjayKumarBasuthkar about 4 years
    Those down voting the answer with or without verifying the functioning of the script, reflects their ability to reason, discover usefulness &/ learn, acknowledge our peers, knowledge & maturity.
  • bballdave025
    bballdave025 about 4 years
    This is the solution I will be using. Very time-efficient, and I like being able to put it in ~/.bashrc.
  • Jeff
    Jeff about 3 years
    @Scott find -exec seems to fail if what I want to do is source the found file, so I'm using for... do...
  • Scott - Слава Україні
    Scott - Слава Україні about 3 years
    @bballdave025: That’s a red herring; all the answers could be put into .bashrc if you wanted to.
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' about 3 years
    The downvotes you’ve gotten so far reflect the belief that you’re answering the wrong question with a skimpy explanation. I wonder why you consider .so files to be executable but not .o files, and why you consider OCaml scripts to be executable but not shell scripts (or Awk, Perl, Python, etc.). Also, your answer has a typo. But THIS downvote is for the snarky, abusive comment.
  • bballdave025
    bballdave025 about 3 years
    Good point, @Scott , and one that shows that my comment is inaccurate. Thanks for pointing it out, so that others will know. Even so, because of the time-efficiency of this process, I choose to put this one in ~/.bashrc, rather than the others.
  • Admin
    Admin almost 2 years
    from the man page -perm +mode This is no longer supported (and has been deprecated since 2005). Use -perm /mode instead.