9

This is my first question although I've been lurking for a while.

Question: I would like to use find to get only the files in a directory with permissions not set to 644 (or another permission value). Is there shorter way to write this or is the only way to just use the -perm and -or options and list each permission type except for 644?

This is part of a larger command that I was hoping to speed up:

find /path/to/dir/ -type f -print0 | xargs -0 chmod 644

I'm hoping that providing xargs only the file names that need updated will speed it up. The directory has ~ a million files but only ~10,000 usually need permissions updated. I think the command is slow because it is still piping all the files regardless. Maybe there is a more efficient approach to the larger command. Let me know if you know of one. I'd still like to know the answer to this question though. And btw, I can't update the permissions before adding the files to the directory.

M Brown
  • 193
  • 1
  • 3
  • The command executes in < 2 seconds when before it took more than 5 minutes so this is a much better method although I never see examples doing it this way. Thanks everyone. find /path/to/dir/ -type f ! -perm 0644 -print0 | xargs -0 chmod 644 – M Brown Jul 30 '10 at 22:12

4 Answers4

19

The ! operator returns true when a condition is false.

So while -perm 0644 matches files that have rw-r--r-- permissions set, ! -perm 0644 matches those that don't have those permissions.

The command you need is:

find /path/to/dir/ -type f ! -perm 0644 -print0 | xargs -0 chmod 644
Kenny Rasschaert
  • 9,045
  • 3
  • 42
  • 58
  • 2
    This works great. The ! flag was exactly what I needed. The query is now almost instant instead of taking ~ 5 minutes. I now see it mentioned in the man file at the bottom. – M Brown Jul 30 '10 at 22:06
3
  find /path/to/dir ! -perm 0644 

And

    find /path/to/dir ! -perm 0644 -exec chmod 0644 {} \;
Jasper
  • 1,084
  • 10
  • 10
3

At least with GNU find, you can use the ! operator for negation with -perm. For example:

find /path/to/dir ! -perm 644

Based on the example you're giving, are you just looking to ensure that the owners have at least read/write and everyone has at least read? If so, then you can just do it with chmod:

chmod -R a+r,u+w /path/to/dir/*
  • The ! operator is what I was missing. I have to use find and then pipe to xargs because of the large number of files in the directory. chmod can't handle the number of files. – M Brown Jul 30 '10 at 22:10
2

One possible solution would be if you have less directories, run a chmod -R 644 /path/to/dir and then run a find /path/to/dir -type d -exec chmod 755 {} \;.

Warner
  • 23,756
  • 2
  • 59
  • 69