6

I'd like to recursively chmod a directory so that:

  • Files are 0664
  • Directories are 0775

How to do it better, shorter, fancier? :) Maybe, use umask somehow?

All find solutions are too long: I always end with Copy-Paste :)

kolypto
  • 11,058
  • 12
  • 54
  • 66
  • I'm thinking a `find`, specifying either directory or file flags, with an -exec to `chmod`... – ewwhite May 04 '12 at 18:01
  • 1
    what do you mean by all find solutions are too long ? – user9517 May 04 '12 at 18:06
  • Too long for being 'handy' to type at once :) – kolypto May 04 '12 at 18:12
  • 1
    If you're doing this so frequently that you can't be subjected to the numbing repetition of the few extra characters of a simple `find`, it begs the question: why not fix the permissions via `umask` (or some program-specific option) so that they're correct in the first place? – BMDan May 04 '12 at 21:30

6 Answers6

15

Depending on your version of chmod, you may be able to do this:

chmod -R . ug+rwX,o+rX,o-w

Note the capital X. This sets the executable bit on directories and files that already have any of the execute bit already set.

Note that you can only use capital X with '+', not '=' or '-'.

wfaulk
  • 6,878
  • 7
  • 46
  • 75
8

Better, shorter, fancier than what ?

cd /directory
find . -type d -exec chmod 0755 {} +
find . -type f -exec chmod 0664 {} +
user9517
  • 115,471
  • 20
  • 215
  • 297
  • aaaw you beat me to it :( – Lucas Kauffman May 04 '12 at 18:02
  • Dangerous with files whose names contain certain reserved characters (like spaces, depending on your version of `find`). Consider `-print0` and `xargs -0`. – BMDan May 04 '12 at 21:27
  • @BMDan: strange as it may seem - it's safe with spaces - I tested it. – user9517 May 04 '12 at 21:30
  • @Iain: I recently discovered this behavior, but I'm not insignificantly baffled by it, and I'm pretty sure `find` hasn't always worked this way. Thus, my "depending on your version" disclaimer. – BMDan May 04 '12 at 21:32
  • @BMDan in the event that find broke up any filenames with spaces (Which I run in to all the time) how would you use -print0 to fix it in this particular situation? – Safado May 04 '12 at 21:34
  • @Safado: `find . type d -print0 | xargs -0 chmod 0755` and `find . -type f -print0 | xargs -0 chmod 0664`. – BMDan May 04 '12 at 21:38
  • Awesome, thank you. I'm assuming the -0 in xargs is required to prevent the same behavior? And I'm guessing using -print0 will still allow for the use of -exec (instead of piping to xargs)? – Safado May 04 '12 at 21:40
4

Adding a oneliner to the mix

find -type f -exec chmod 0644 {} + -o -type d -exec chmod 0755 {} +
Dima Chubarov
  • 2,316
  • 1
  • 17
  • 28
3
find /dir -type f -print0 |xargs -0 chmod 0644
find /dir -type d -print0 |xargs -0 chmod 0775

Test it before use it in real environment

jscott
  • 24,484
  • 8
  • 79
  • 100
NoNoNo
  • 1,963
  • 14
  • 20
1

I am using this for anything copied from FAT filesystems:

chmod -R a-x+X .

If it does not work, for example on Mac OS X, try the GNU version of the command chmod:

gchmod -R a-x+X .
Messa
  • 219
  • 3
  • 8
1

Without knowing more about why you're trying to do this, the most common reasons people tend to use are either:

  • Files and directories are other-writeable

    chmod -R o-w /path/to/dir

  • Files and directories are not group-writeable

    chmod -R g+w /path/to/dir

Or, combine the two:

chmod -R o-w,g+w /path/to/dir

Alternately, if you want files and directories to the correct permissions by default, modify the creating process's umask.

Basically, it's a rare day that it's correct to use numeric modes with chmod; typically, directories already have the executable bit set and files that don't need it lack it, so why muck around with it at all when the + and - operators obviate the need to do so?

BMDan
  • 7,249
  • 2
  • 23
  • 34