Linux ext4 restore file and directory access rights after bad backup/restore

Solution 1:

The standard recommended solution is straight-forward:

find . -type d -exec chmod 0755 "{}" \+
find . -type f -exec chmod 0644 "{}" \+

This will append as many filenames as possible as arguments to a single command, up to the system's maximum command line length. If the line exceeds this length, the command will be called multiple times.

If you want to call the command once per file, you can instead do:

find . -type d -exec chmod 0755 "{}" \;
find . -type f -exec chmod 0644 "{}" \;

Solution 2:

chmod -R a=,u+rwX,go+rX $DIR seems to work fine, and is very likely to be the fastest, however you look at it.

(I checked with strace, and it makes only one fchmodat() syscall per file/directory -- for files that is with 644 and for directories with 755).

The trick is the X permmission, documented in man chmod, which acts like x for directories only -- the very distinction you wanted.

What is not documented is my guess that they would be applied in the same sequence as they are specified, and not just in some random order, but repeated tests with several variants have convinced me that they do indeed run in the order given, so I am pretty sure this is always going to work like this.

I should mention this is on Linux, though a cursory reading of the BSD manpage for chmod suggest that it should work there also.