I'm writing a find command to look for files or folders with broken permissions (files should be rw, directories rwx) and trying to ls -l (give or take) the results.

The following find command looks like it works, but the ls part is giving me trouble.

find . '(' -not -readable ')' -or \
       '(' -not -writable ')' -or \
       '(' '(' -not -executable ')' -and -type d ')'

Adding -ls or -exec ls -l {} \; to the end works until it gets to a directory it can't read. That gives a permission denied error and bails out completely without finishing. Running ls -ld $(<that command>) works, as far as I can tell, but it feels like I'm missing something simple in find.

As an aside, I'm not worried about POSIX compliance, so I'd rather use -or instead of -o and such for readability.

  • 1
    -exec ls -ld {} +? – Kevin Jul 3 '14 at 20:22
  • 1
    weird find . '(' -not -readable ')' -or \ '(' -not -writable ')' -or \ '(' '(' -not -executable ')' -and -type d ')' -exec ls -l {} \; works for me... What version of find you have? – Braiam Jul 3 '14 at 20:23
  • @Kevin, same result. @Braiam, 4.4.2, Ubuntu. Adding more test cases, it doesn't seem to bail entirely, but it does change the result (it ignores other files, for some reason) and it doesn't actually ls -l the unreadable folders. – Jason Lefler Jul 3 '14 at 20:53
  • Oh, I see what's going on. – Kevin Jul 3 '14 at 20:55
  • 2
    Note that putting -ls at the end will do an implicit -and. Since -and binds more tightly than -or, only directories will be listed. You probably want to add one more set of parentheses around the three conditions that are ored together. – Mark Plotnick Jul 3 '14 at 22:28

Once you hit a directory that's not executable, find tries to go into it, but it can't because, well, it's not executable. You need to tell it not to try by using -prune.

And put that condition first, so it's not short-circuited.

find . '(' '(' -not -executable ')' -and -type d -and -prune ')' -or \
       '(' -not -readable ')' -or \
       '(' -not -writable ')'
  • In a blank directory, mkdir dir && touch file && chmod 440 *. The find without -ls or -exec finds them both. Adding either returns nothing, and -prune doesn't seem to do anything in this case. – Jason Lefler Jul 3 '14 at 21:09
  • Move the prune part to the beginning, it's passing the not writeable condition so it doesn't get to the prune. – Kevin Jul 3 '14 at 21:16
  • That does indeed prevent the permission denied errors, so it's helpful, but adding -ls or -exec returns a different result (missing the directory). I'm guessing that that's a different question altogether and this should be accepted? – Jason Lefler Jul 3 '14 at 21:31
  • Put an additional -ls before the -prune – Kevin Jul 3 '14 at 21:34
  • That did it. For clarification, the extra -ls or -exec had to go before or after the -prune because the -prune was short circuiting the rest of the command. – Jason Lefler Jul 3 '14 at 21:37

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.