I'm searching for all files that contain one of a set of strings. If they do, I change their access rights.

 find . -type f -exec grep -q '#!/bin/bash\|#!/usr/bin/grep\|#!/usr/bin/awk' {} \; -exec chmod 700 {} ;\

I'm curious how the find works when it finds a file containing that string grep -q gives me 0 so another exec executes but should not. That second exec finds all files and change the rights to all files. Why does it work and change only those files containing that string?

  • @mnille if you are going to edit a post for formatting anyway, please read through the whole and fix the (many) other issues as well. – Anthon May 2 '16 at 11:33
  • BTW, you might want to try it with this grep command instead: ... -exec grep -E -q '#! *(/usr)?(/local)?/bin/([bd]ash|[zk]sh|t?csh|awk|sed|perl)' ... (note: I removed the pattern that matches /usr/bin/grep because that makes no sense, grep is not a scripting language. Added dash, zsh, ksh, tcsh/csh, sed and perl instead). – cas May 2 '16 at 12:36
  • 1
    @cas why not just search for shebangs in general? Presumably, the OP wants to find all script files. Searching for #! makes more sense than trying to guess al possible interpreters. – terdon May 2 '16 at 12:40
  • 1
    um, yeah. duh. that makes more sense. also worth making sure that the #! is both at the start of the line, AND is the first line of the file. – cas May 2 '16 at 12:40

I am not sure what your intention is (you didn't make that clear), but if it's to chmod to 700 all the files that match the pattern, then, except for your typo (;\ instead of \;), your command seems to work as intended.


when it finds a file containing that string grep -q gives me 0 so another exec executes but should not.

Yes, it should do. 0 means success means true, so find continues to evaluate its expression, and the second -exec runs. 1 (or any value other than 0) would mean failure would mean false, so find would short-circuit its evaluation (there is an implicit logical AND between juxtaposed expressions) so the second -exec does not run.

Why does it work

Check the manpage for GNU find:

expr1 expr2

Two expressions in a row are taken to be joined with an implied "and"; expr2 is not evaluated if expr1 is false.

| improve this answer | |

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.