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. – user74422 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. – user74422 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? – user74422 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. – user74422 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