73

why doesn't this work I am trying to change all files to 644 abd all -d to 755:

find . -type f -exec chmod 644 {} ;

i get: find: missing argument to `-exec' thanks

Flow
  • 23,572
  • 15
  • 99
  • 156
user1920187
  • 802
  • 1
  • 7
  • 15
  • 9
    Terminate with `\;` not with `;` alone. – Michael Berkowski Nov 02 '13 at 00:22
  • 9
    ...that's because everything following `-exec` is treated as its argument. If you had a bare `;` it would be treated as a terminator for the entire `find`, but really you need to terminate the `exec`, so it must be escaped as a part of the argument string. – Michael Berkowski Nov 02 '13 at 00:24
  • possible duplicate of [How to set chmod for a folder and all of its subfolders and files in Linux Ubuntu Terminal?](http://stackoverflow.com/questions/3740152/how-to-set-chmod-for-a-folder-and-all-of-its-subfolders-and-files-in-linux-ubunt) – Michael Berkowski Nov 02 '13 at 00:25
  • 1
    @MichaelBerkowski Thank You!!!! – Nick Rolando Jun 26 '20 at 22:40

3 Answers3

174

Piping to xargs is a dirty way of doing that which can be done inside of find.

find . -type d -exec chmod 0755 {} \;
find . -type f -exec chmod 0644 {} \;

You can be even more controlling with other options, such as:

find . -type d -user harry -exec chown daisy {} \;

You can do some very cool things with find and you can do some very dangerous things too. Have a look at "man find", it's long but is worth a quick read. And, as always remember:

  • If you are root it will succeed.
  • If you are in root (/) you are going to have a bad day.
  • Using /path/to/directory can make things a lot safer as you are clearly defining where you want find to run.
Phil
  • 1,809
  • 1
  • 12
  • 7
  • 6
    Why would the xargs method be a "dirty way"? It has the huge advantage of running chmod only once, with all files as arguments. The "-exec chmod" method will create a subprocess per file. – Déjà vu Sep 10 '15 at 14:55
  • 4
    If you want to only run chmod once, then change it to `find . -type f -exec chmod 0644 {} +` which works essentially the same as the xargs method, building one command line. (The \ above is only to escape the semicolon.) – johnthacker Aug 02 '16 at 15:49
  • Quick oneliner: `find . -type d -exec chmod 0755 {} \; && find . -type f -exec chmod 0644 {} \;` – lucaferrario Dec 29 '17 at 11:18
  • 2
    Note - xargs is generally superior to exec. With exec, the command is invoked for EACH input but with xargs the command is usually just run ONCE. So if your find query gives thousands of results, xargs will be several folds faster ! – MarcoZen Jul 05 '21 at 14:10
21

A good alternative is this:

find . -type f | xargs chmod -v 644

and for directories:

find . -type d | xargs chmod -v 755

and to be more explicit:

find . -type f | xargs -I{} chmod -v 644 {}
Seth Malaki
  • 4,436
  • 23
  • 48
15

I need this so often that I created a function in my ~/.bashrc file:

chmodf() {
        find $2 -type f -exec chmod $1 {} \;
}
chmodd() {
        find $2 -type d -exec chmod $1 {} \;
}

Now I can use these shortcuts:

chmodd 0775 .
chmodf 0664 .
Fabian Schmengler
  • 24,155
  • 9
  • 79
  • 111