0

I want to find all the files and directories that have a group different from the owner.

So if these were the two files in the directory, I'd want to just find the first one:

$> ls -l
-rw-rw-r--. 1 user175 group192  866 Dec 12  2006 index.htm
-rw-r--r--. 1 user175 user175   921 Dec 14  2006 index2.html

I've been playing with find, but I'm starting to think I'm going to have to give up and write some kind of script (I'd really rather not write a script).

Thanks in advance.

  • There are a thousands of directories in Linux. Are you sure you want to do this for all directories existing on your machine? Or for specific ones? If the latter, then the task is a lot easier. – Fanatique Jul 27 '18 at 14:25
1
find . -exec sh -c '
      stat -c "%U %G" "$1" |
      awk -F " " "\$1==\$2{exit 1}"
   ' sh {} \; -print

It runs stat for every object, retrieves its owner and group; awk then returns exit status 0 only if they differ. In effect only these are printed.

Notes:

  • The performance is low. Each object needs its own separate sh, stat and awk. I had some ideas to improve this (find . -exec stat … {} + | awk …) but I'm not sure I can make them robust enough to work with possible filenames with newlines etc. I decided to play it safe. You can use -print0 if needed. This approach also allows you to add more conditions to find.
  • In my Kubuntu stat -c "%U %G" returns UNKNOWN for UIDs (or GIDs) that cannot be translated to names. If there is a user UNKNOWN or a group UNKNOWN, this will interfere, I think. An object returning UNKNOWN UNKNOWN is naively interpreted to have matching owner and group.
  • This takes forever even in a directory with few files, but it does seem to work in all cases. Thanks. – Jistanidiot Aug 3 '18 at 14:28
0

Well, I found a different solution that uses ls and awk instead of find. And this certainly needs and can be optimized. Here it goes :

ls -alR | awk '{ if ($3 != $4) print $0 }'

How it Works :

  • See what -alR does from man ls
  • awk searches for the pattern.
  • $3 & $4 correspondingly gives 3rd & 4th column in ls output that are file owner and group that owner is a part of.
  • $0 gives complete line in ls output.
  • Condition if ($3 != $4) print $0 interprets to " Print complete line with all columns wherein value in 3rd column is not equal to value in 4th column "
  • Complete command can be interpreted as Print only those line in ls output where file owner name and group name is not the same.

Limitation :

Sometimes, It gives this error for some files :

ls: cannot open directory './chatscripts': Permission denied

As far as I understand, It's a permission issue with the user from which command is being executed. The user is neither owner nor a part of group for that file and thus cannot access it.


What you want can be definitely done with find command, but I think this can be a solution too and also there still will be this permission issue If you do it with find command.

Feel free to add-in more details.

  • This seems to work until you hit one of the problem file/directory names as mentioned in "why you shouldn't parse the output of ls". – Jistanidiot Aug 3 '18 at 14:26

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.