CHMOD - Applying Different Permissions For Files vs. Directories

Solution 1:

No need for scripts.

// Directories:

find . -type d -exec chmod XXX {} \;

// Files:

find . -type f -exec chmod XXX {} \;

Solution 2:

In your case it might not have to be as complicated as others has made it out to be (though find is indeed a good tool for this sort of thing in general). The difference between the modes are the execute bit. If it is the case that no files already has the execute bit set, then you can do it in a single invocation of chmod, just as you asked.

chmod -R u=rwX,g=rwX,o= FILE...

The key here is the capital X, which the man page explains as

execute/search only if the file is a directory or already has execute permission for some user.

Thus, if your files do not already have the execute bit set, it will only be set for directories.


Solution 3:

I do find a script useful since it's often useful to change both file and directory permissions in one swoop, and they are often linked. 770 and 660 for shared directories on a file server, 755/644 for web server directories, etc. I keep a script w/ the most commonly used mode for that type of server in root's bin/ and just do the find manually when the common mode doesn't apply.

#!/bin/sh
# syntax: setperm.s destdir
#
if [ -z $1 ] ; then echo "Requires single argument: <directoryname>" ; exit 1 ;                                       fi

destdir=$1

dirmode=0770
filemode=0660

YN=no

printf "\nThis will RECURSIVELY change the permissions for this entire branch:\n                                      "
printf "\t$destdir\n"
printf "\tDirectories chmod = $dirmode\tFiles chmod = $filemode\n"
printf "Are you sure want to do this [$YN]? "

read YN

case $YN in
        [yY]|[yY][eE][sS])
        # change permissions on files and directories.
        find $destdir -type f -print0 | xargs -0 chmod $filemode $i
        find $destdir -type d -print0 | xargs -0 chmod $dirmode $ii ;;

        *) echo "\nBetter safe than sorry I always say.\n" ;;
esac

Solution 4:

I found that for my use case at least, using rsync to copy the directory onto itself was much faster than using chmod directly with a list of files from find.

rsync -rpt --chmod=D770,F660 . .

If you want to add a chown to the same operation, rsync lets you do that too with the --chown=user:group option.