vpalos.com // milk, cookies, segfaults…

Recursive chmod distinguishing files from folders

by Valeriu Paloş on December 16, 2009

Version 3

An even better method is:

find "$target" -type f -exec chmod -c "$mode_files" {} \; \
     -or -type d -exec chmod -c "$mode_dir" {} \;

A true one-liner! 😀

Version 2

A better method is this:

find "$target" -type f -exec chmod -c "$mode_files" {} \;
find "$target" -type d -exec chmod -c "$mode_dir" {} \;

This one can also be used from the command line.

Version 1

Many times I needed to apply certain permissions recursively on a given path but with different permissions on files than on directories (i.e. I want 0644 for files and 0744 for directories). This behaviour is not provided by the chmod tool so here is a simple and effective bash function to do just that:

# Recursively apply chmod to path.
# If mode_files is missing then apply mode_dir to files too.
# Params: target mode_dir [mode_files]
function deep_chmod() {
    function _walk() {
        local F
        for F in `find "$1"`; do
            local M="$3"; [[ `file -b "$F"` == "directory" ]] && M="$2"
            chmod -c "$M" "$F" > /dev/null
        done
    }
    if [[ $# > 2 ]]; then
        _walk "$1" "$2" "$3"
    else
        chmod -Rc "$2" "$1"
    fi
}

I’m looking for a way to improve on this since it is quite costly for large directories: for each file or directory at least two programs are executed (file and chmod) which is not very efficient! For now, it gets the job done.

Enjoy! :)

Don't keep it to yourself!...