I'm looking for all setuid/setgid files.
When I don't use -exec
, it works as expected:
# find /usr/bin -type f -perm -4000 -o -perm -2000
/usr/bin/wall
/usr/bin/ksu
/usr/bin/chage
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/fusermount
/usr/bin/passwd
/usr/bin/write
/usr/bin/su
/usr/bin/umount
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/mount
/usr/bin/pkexec
/usr/bin/crontab
/usr/bin/cgclassify
/usr/bin/cgexec
/usr/bin/ssh-agent
/usr/bin/Xorg
/usr/bin/at
/usr/bin/sudo
/usr/bin/locate
/usr/bin/staprun
When I use -exec
, I only get a subset of the results back:
# find /usr/bin -type f -perm -4000 -o -perm -2000 -exec ls -l {} \;
-r-xr-sr-x. 1 root tty 15344 Jan 27 2014 /usr/bin/wall
-rwxr-sr-x. 1 root tty 19536 Aug 21 2015 /usr/bin/write
-rwxr-sr-x. 1 root cgred 15624 Sep 21 2014 /usr/bin/cgclassify
-rwxr-sr-x. 1 root cgred 15584 Sep 21 2014 /usr/bin/cgexec
---x--s--x. 1 root nobody 306304 Sep 24 2015 /usr/bin/ssh-agent
-rwx--s--x. 1 root slocate 40504 Jan 26 2014 /usr/bin/locate
Why?
You're only using
-exec
on the right-hand side of the-o
. Thus, it's being parsed like this:Obviously, that's not what you want.
To make it apply to both sides of the conditional, add some parens for grouping:
The reason is that if you don't specify an explicit action,
find
assumes a-print
as the default action. When you add an action yourself it turns off that default, so only the items for which you explicitly specify an action get one.That is to say:
Note that last one, which exposes a caveat in the default behavior: You probably wanted the
-type f
to apply to both sides of the-o
, but without explicit grouping it gets put on the left, just as an explicit-exec
orprint
gets put on the right.Moral of this story: When using
-o
in find, be explicit about your grouping unless you're very certain that the default behavior is what you want.