26

I have a folder myfolder that contains a huge hierarchy of files/folders.
How to find all executable files within this folder?

On Ubuntu this works: find . -executable -type f

But Mac OS X Mavericks (which also uses bash) fails to get it:

find: -executable: unknown primary or operator

5 Answers 5

39

This will find all files (not symlinks) with the executable bit set:

find . -perm +111 -type f

This will also find symlinks (which are often equally important)

find . -perm +111 -type f -or -type l

Here's how the command works if its not obvious:

  • find is obviously the find program (:
  • . refers to the directory to start finding in (. = current directory)
  • -perm +111 = with any of the executable bits set (+ means "any of these bits", 111 is the octal for the executable bit on owner, group and anybody)
  • -type f means the type is a file
  • -or boolean OR
  • -type l means the type is a symbolic link
2
  • 2
    You can use -L instead of -or -type l to cause any stat calls made by find to return the stats of the file linked to, not the link itself.
    – Ian C.
    Jan 8, 2014 at 7:27
  • 1
    The problem I found with this approach is that any file can have the run permission. For example, after you download some text file from Windows, the permission is messed up.
    – Ivan Xiao
    Oct 16, 2014 at 20:54
5

I couldn't make Ian's answer work (10.6.8), but, the following gave the expected results:

find . -type f -perm +0111 -print

edit update

This seems to work as well!

find . -type f -perm +ugo+x -print

I guess the "x" is meaningless without the user/group/other specifiers.

3
  • Symbolic syntax must be new -- thanks for pointing that out. I updated my answer so it uses octals and is backwards compatible with older OS X versions.
    – Ian C.
    Jan 8, 2014 at 7:26
  • Oddly enough, that section of the 10.6 manpage is exactly the same as what you quoted.... which was enough to make me dig a little deeper and see what the heck was going on. Amended my response above.
    – Kent
    Jan 8, 2014 at 7:49
  • 2
    Conclusion: BDS command syntax is weird.
    – Ian C.
    Jan 8, 2014 at 7:54
4

From the man page for find in OS X:

 -perm [-|+]mode
         The mode may be either symbolic (see chmod(1)) or an octal number.  If the mode is symbolic, a
         starting value of zero is assumed and the mode sets or clears permissions without regard to the
         process' file mode creation mask.  If the mode is octal, only bits 07777 (S_ISUID | S_ISGID |
         S_ISTXT | S_IRWXU | S_IRWXG | S_IRWXO) of the file's mode bits participate in the comparison.
         If the mode is preceded by a dash (``-''), this primary evaluates to true if at least all of
         the bits in the mode are set in the file's mode bits.  If the mode is preceded by a plus
         (``+''), this primary evaluates to true if any of the bits in the mode are set in the file's
         mode bits.  Otherwise, this primary evaluates to true if the bits in the mode exactly match the
         file's mode bits.  Note, the first character of a symbolic mode may not be a dash (``-'').

So you need:

find . -type f -perm +0111 -print

Remember that OS X is BSD-based, not Linux based, so the Gnu commands you're used to in Linux distributions (of which find is one of them) aren't necessarily the same as they are in OS X. This isn't a shell difference, it's an operating system/operating system utility tools difference.

3

A very old question, I'm aware, but searching for a solution I may have found a better answer.

The main problem with using "find" is that it relies on an attribute set to executable, even if this attribute is set for a non-executable file.

MacOS comes with a handy little command-line tool "file", which displays file information, for example:

$> file *

Distribution:             directory
SomeFile.icns:            Mac OS X icon, 3272878 bytes, "ic09" type
MyPicture.png:            PNG image data, 1024 x 1024, 8-bit/color RGBA, non-interlaced
NSHelpers.pas:            Algol 68 source text, ASCII text
myProgram:                Mach-O 64-bit executable x86_64

As you can see, 'MyProgram' is an executable, and nicely indicated as such. Since old 32bit executables will have the phrase "executable" in this as well, the following should list all true executable (binaries):

file * | grep "executable"

Hope this will be useful to somebody looking for an answer to the same question as well.

Note: file does not seem to have a function to recurse through subdirectories.

2

I believe @Hanzaplastique is on the right path, but to do 'find' correctly, I would use:

find . -type f -exec bash -c "file {} | grep 'executable'" \;

You can also add -name "*some_wild_card*" after the . to filter for specific type of executables. And of course, you can replace bash with your favorite shell.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .