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.

  • 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, 2010 at 22:12

4 Answers 4


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
  • 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, 2010 at 22:06
  find /path/to/dir ! -perm 0644 


    find /path/to/dir ! -perm 0644 -exec chmod 0644 {} \;
  • /path/to/dir has to be before the !. 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?
    – M Brown
    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. Jul 30, 2010 at 22:19

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

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

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.