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.

1
  • 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 Commented Jul 30, 2010 at 22:12

4 Answers 4

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 
1
  • 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. Commented Jul 30, 2010 at 22:06
3
 find /path/to/dir ! -perm 0644 

And

 find /path/to/dir ! -perm 0644 -exec chmod 0644 {} \; 
3
  • /path/to/dir has to be before the !. Commented Jul 30, 2010 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? Commented Jul 30, 2010 at 22:07
  • 2
    @M Brown, in the future, try using + instead of \;. That will do the same kind of batching as xargs. Commented Jul 30, 2010 at 22:19
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/* 
1
  • 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. Commented Jul 30, 2010 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 {} \;.

1
  • There are no directories only files. I use xargs because of the large number of files. Commented Jul 30, 2010 at 22:09

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.