I want to set access permissions for a large number of files and directories. In How to improve performance of changing files and folders permissions? and https://superuser.com/a/91938/813482, several variants to set permissions are presented, among others:
Variant 1:
find /path/to/base/dir -type d -exec chmod 755 {} +
find /path/to/base/dir -type f -exec chmod 644 {} +
Variant 2:
find /path/to/base/dir -type d -print0 | xargs -0 chmod 755
find /path/to/base/dir -type f -print0 | xargs -0 chmod 644
Variant 3:
chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)
Which of these should be the most efficient? In a quick test for the directory I'm using, compared to variant 1, variant 2 reduced the time from more than 30 to more than 3 sec (one order of magnitude), since it does not need to call chmod
for every file separately. Variant 3 gave warnings, since some directory names/filenames contain spaces and it cannot access those directories. Variant 3 may even be slightly faster than variant 2, but I'm not sure since this may be related to not being able to enter the directories(?).
Which of these should be the most efficient?
Variant 1.
I you really want speed, traverse once, not twice.
find /path/to/base/dir '(' -type d -exec chmod 755 {} + ')' -o '(' -type f -exec chmod 644 {} + ')'
Variant 2 is great if the number of files or directories is greater than the maximum number of arguments on a platform.
Variant 3 is very bad, where the result of find is not quoted, and the shell will do word splitting and filename expansion. It will fail badly if any path has, for example, a space or a star.