QR Code contains TinyURL of this article.Recursive chmod

I often find myself in a position where I need to recursively chmod a collection of files or folders. This is especially true when I am preparing files for Web delivery and I want to set them as read only (chmod 0444 filename). I normally do this using a combination of find and chmod. For example: find . -type f -exec chmod 0444 {} \;

“Wouldn’t it be cool,” I thought, “to have a rchmod (recursive chmod) command?”

So I put the together the following Bash script (source available on GitHub):

#!/bin/sh

# Traverse a directory starting at $path and change the permissions of all files
# or folders (determined with options) to $permissions

helpText=$"Usage: ${0##*/} -(f|d) permissions path";
permissions=$2;
path=$3;
if [[ $path ]]
  then
  if [[ ! -d $path ]]
    then
      echo "Path not found: $path";
      exit 1;
  fi
fi

while getopts "fd:" mode; do
  case $mode in
    f)
      find "$path" -type f -exec chmod "$permissions" {} +
      exit 0;
      ;;
    d)
      find "$path" -type d -exec chmod "$permissions" {} +
      exit 0;
      ;;
    *)
      echo $helpText;
      exit 1;
  esac
done

echo $helpText;
exit 1;

Save this script in your $PATH as rchmod and make it executable.

Using it is as simple as:

  1. rchmod -f +rw path - make all the files in the path directory (and its descendants) readable and writable for the currently logged-in user;
  2. rchmod -d +r path - make all directories in the path directory, its descendants and the path directory itself readable for the currently logged-in user;
  3. rchmod -f 0666 path - set the permissions of all files in the path directory and its descendants to 0666.

NOTE: rchmod -f 0444 /web/*.html - will not do what you might expect! The result here would be that all files with a html extension in the directory /web would have their permissions set to 0444, but there would be no further directory traversal (i.e.: no recursion).