performanceshellfile-permissionschmod

Fastest way to set access permissions for a large number of files / directories?


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(?).


Solution

  • 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.