The solution to this problem has been evading me for weeks. I am attempting to write a command to find only world writable files in a specific set of directories without traversing into any sub directories using -prune.

I have attempted a multitude of different options only to be left with

find / -type f -perm -2

This however, still traverses into the sub-directories. Using the command

find / -prune -type f -perm -2

yields no results either. Where am I going wrong with this?


Try using maxdepth N instead:

-maxdepth levels
Descend at most levels (a non-negative integer) levels of directories below the starting-points. -maxdepth 0 means only apply the tests and actions to the starting-points themselves.

find $FOLDER -maxdepth 1 -perm -2
  • Add -mindepth 1, otherwise you're also matching the starting directory itself. (It doesn't matter if the only action is behind a -type f of course.) – Gilles 'SO- stop being evil' Sep 24 '16 at 23:30
find / -type f -perm -2

This is recursive. That's what find does.

find / -prune -type f -perm -2

Here, you're instructing find to apply -prune to everything it finds. The conditions and actions are processed from left to right; since there's no condition before -prune, it's applied unconditionally. So the first thing that find finds, which is the command line argument /, has -prune applied to it, and so find doesn't traverse the content of the directory. Since / doesn't match the following conditions, it isn't printed.

To process only the entries of the toplevel directory, you need to apply -prune to the directories except the command line arguments. The portable way to do this is to use /. at the end of path passed on the command line. This causes find to treat their name as ., so you can use -name . to match them. In a recursive traversal, no file is ever called . since this name is reserved. Now there are three different cases:

  • Toplevel directory: recurse.
  • Other directory: don't recurse.
  • Regular file that are world-writable: print.

To specify several different behaviors, use the -o (“or”) operator. The first one for which all conditions match applies.

find /. -name . -o -type d -prune -o -type f -perm -2 -print

Some versions of find allow you to write find / -name / -o -type d -prune -o … but some don't (e.g. BusyBox).

Some versions of find support options -mindepth and -maxdepth to constrain the recursive traversal. If your find supports it, you can use this instead of -prune.

find / -mindepth 1 -maxdepth 1 -type f -perm -2

(-mindepth and -maxdepth are global options, the conditions-and-actions part is -type f -perm -2 with the implicit trailing -print.)

  • Much appreciated Gilles! This does exactly what I need it to. Min and Maxdepth are not an option as our environment uses several flavors of *nix. – M L Sep 27 '16 at 15:53

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.