Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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.

share|improve this question
    
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 Answers 4

up vote 12 down vote accepted

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
share|improve this answer
1  
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

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/*
share|improve this answer
    
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

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 {} \;.

share|improve this answer
    
There are no directories only files. I use xargs because of the large number of files. –  M Brown Jul 30 '10 at 22:09
  find /path/to/dir ! -perm 0644 

And

    find /path/to/dir ! -perm 0644 -exec chmod 0644 {} \;
share|improve this answer
    
/path/to/dir has to be before the !. –  Matthew Flaschen Jul 30 '10 at 21:33
    
This works also but for whatever reason -exec is slower than piping to xargs for this since it is a large directory. -exec might be performing individual commands instead of batching like xargs? –  M Brown Jul 30 '10 at 22:07
2  
@M Brown, in the future, try using + instead of \;. That will do the same kind of batching as xargs. –  Matthew Flaschen Jul 30 '10 at 22:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.