Assuming the use of chmod from the GNU coreutils package on Ubuntu 12.10.
chmod 775 . -R executes the fchmodat system call for each file that it finds irrespective of whether the permissions need changing or not. I confirmed this by both inspecting the code and using strace chmod 775 . -R (snippet below) to list the actual behaviour.
newfstatat(4, "d", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0 fchmodat(4, "d", 0775) = 0 newfstatat(4, "c", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0 fchmodat(4, "c", 0775) = 0 newfstatat(4, "a", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0 fchmodat(4, "a", 0775) = 0 newfstatat(4, "b", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0 fchmodat(4, "b", 0775) = 0
There are a couple of disadvantages of running fchmodat on each file
- The extra system call will likely become significant if a large number of files are changed. The
find/xargs/chmod method mentioned by others will likely be quicker by only changing files that need changing. - The call to
fchmodat changes the file status modification (ctime) of each file. This will cause every file/inode to change each time and will likely cause excess disk writes. It might be possible to use mount options to stop these excess writes.
A simple experiment shows the ctime changes happening for straight chmod
auser@duncow:/tmp/blah.test$ ls -lc total 0 -rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 a -rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 b -rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 c -rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 d auser@duncow:/tmp/blah.test$ chmod 775 . -R auser@duncow:/tmp/blah.test$ ls -lc total 0 -rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 a -rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 b -rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 c -rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 d
But this does not change for find/xargs/chmod a few minutes later
auser@duncow:/tmp/blah.test$ date Tue Jun 18 18:27:27 BST 2013 auser@duncow:/tmp/blah.test$ find . ! -perm 775 -print0 | xargs -0 -I {} chmod 775 {} auser@duncow:/tmp/blah.test$ ls -lc total 0 -rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 a -rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 b -rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 c -rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 d
I would always tend to use the find/xargs/chmod version because find gives more control over selecting things.