Use Chmod Command Selectively

chmodcommand linefind

I want to set 755 permission on all files and sub-directories under a specific directory, but I want to execute chmod 755 only for those components which does not have 755 permission.

find /main_directory/ -exec chmod 755 {} \;

If the find command returns a long list, this will take a lot of time.
I know that I can use the stat command to check the Octal file level permission of each component and then use if-else to toggle the file permission, but is there any single line approach using find and xargs to first check what permission the file/directory has, and then use chmod to change it to 755 if it is set to something else.

Best Answer

If you want to change permissions to 755 on both files and directories, there's no real benefit to using find (from a performance point of view at least), and you could just do

chmod -R 755 /main_directory

If you really want to use find to avoid changing permissions on things that already has 755 permissions (to avoid updating their ctime timestamp), then you should also test for the current permissions on each directory and file:

find /main_directory ! -perm 0755 -exec chmod 755 {} +

The -exec ... {} + will collect as many pathnames as possible that passes the ! -perm 0755 test, and execute chmod on all of them at once.

Usually, one would want to change permissions on files and directories separately, so that not all files are executable:

find /main_directory   -type d ! -perm 0755 -exec chmod 755 {} +
find /main_directory ! -type d ! -perm 0644 -exec chmod 644 {} +