38

I have to change the permissions of the htdocs directory in apache to a certain group and with certain read/write/execute.

The directories need to have 775 permissions and the files need to have 664.

If I do a recursive 664 to the htdocs, then all files and directories will change to 664.

I don't want to change the directories manually.

Is there any way to change only files or directories?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
radicaled
  • 2,369
  • 5
  • 30
  • 44

7 Answers7

73

chmod can actually do this itself; the X symbolic permission means "execute, if it makes sense" which generally means on directories but not files. So, you can use:

chmod -R u=rwX,go=rX /path/to/htdocs

The only potential problem is that if any of the plain files already have execute set, chmod assumes it's intentional and keeps it. If this is a potential problem and you have the GNU version of chmod (i.e. you're on Linux), you can get it to remove any stray execute permissions like this:

chmod -R a-x,u=rwX,go=rX /path/to/htdocs

Unfortunately, this trick doesn't work with the bsd (/macOS) version of chmod (I'm not sure about other versions). This is because the bsd version applies the X permission based on "the original (unmodified) mode", i.e. whether it had any execute bits before the a-x modification was done (see the man page).

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151
  • 3
    Best Answer by far, if you have enough recursive directories, `xargs` will fail eventually. check the [man pages](http://ss64.com/bash/chmod.html) for more info – Jared Scott Oct 16 '14 at 05:55
  • 1
    To combat the potential problem of existing execute flags remaining, you can use: `chmod -R a-rwx,u+rwX,go+rX` This effectively removes all permissions for user, group and other and then only adds those that you want. – Axel Wilczek Sep 05 '21 at 23:52
  • @AxelWilczek Unfortunately, that trick only works with some versions of `chmod`. But I'll add it my answer with an explanation. – Gordon Davisson Sep 06 '21 at 00:09
44

Use find's -type option to limit actions to files and directories. Use the -o option to specify alternate actions for different types, so you only have to run find once, rather than separately for each type.

find htdocs -type f -exec chmod 664 {} + -o -type d -exec chmod 775 {} +
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 4
    Better to use `chmod`s built in support. See [Gordon Davisson's](http://stackoverflow.com/a/17091413/538512) answer below – Jared Scott Oct 16 '14 at 05:56
  • This method is better because if you have a mess of 'x' on basic files that don't need it, this `find` method above cleans them all up, while the `u=rwX,go=rX` does not clean anything up. – IncredibleHat Jan 24 '19 at 19:38
  • This worked like a charm and saved hours of work. Thank you!! – cbloss793 Nov 21 '19 at 17:03
5

Use find to search for directories and apply chmod on them:

find -type d | xargs chmod 775

Use type f for file:

find -type f | xargs chmod 775
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Amit
  • 19,780
  • 6
  • 46
  • 54
4

Gordon's answer above is correct, but if you're trying to lock down access to a directory tree, it leaves scripts that are executable to the owner also executable to whoever has been granted the capital X.

Using

find <path> -type d -exec chmod 775 {} +

or

find <path> -type d -exec chmod 755 {} +

is safer.

MartinMlima
  • 1,736
  • 1
  • 12
  • 13
4

I use something similar to the solution provided by Gordon:

chmod -R ug=rw,o=r,a+X /path/to/folder/

It should always set 775 for folders and 664 for files, even if the execute permission was previosly set for some file

genna
  • 461
  • 1
  • 6
  • 17
2

try:

find htdocs -type d -exec chmod 775 {} +
chepner
  • 497,756
  • 71
  • 530
  • 681
RicardoE
  • 1,665
  • 6
  • 24
  • 42
-1

for dirs or files

chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)
wyx
  • 3,334
  • 6
  • 24
  • 44