Wednesday, September 11, 2013

Linux / UNIX: Change File Permissions Recursively with or without condition

To change file access permissions you need to use the chmod command.


It has -R or --recursive option that change files and directories recursively. The find command can be used to find files and directories.
The chown command can be used to change user and group permission

chown command

chown command changes the user and/or group ownership of for given file. The syntax is:


chown owner-user file
chown owner-user:owner-group file
chown owner-user:owner-group directory
chown options owner-user:owner-group file

Examples

First, list permissions for demo.txt, enter:
# ls -l demo.txt

Sample outputs:

-rw-r--r-- 1 root root 0 Aug 31 05:48 demo.txt
In this example change file ownership to thomas user and list the permissions, run:
# chown thomas demo.txt
# ls -l demo.txt

Sample outputs:

-rw-r--r-- 1 thomas root 0 Aug 31 05:48 demo.txt
In this next example, the owner is set to thomas followed by a colon and a group onwership is also set to thomas group, run:
# chown thomas:thomas demo.txt
# ls -l demo.txt

Sample outputs:

-rw-r--r-- 1 thomas thomas 0 Aug 31 05:48 demo.txt
In this example, change only the group of file. To do so, the colon and following GROUP-name ftp are given, but the owner is omitted, only the group of the files is changed:
# chown :ftp demo.txt
# ls -l demo.txt

Sample outputs:

-rw-r--r-- 1 thomas ftp 0 Aug 31 05:48 demo.txt
Please note that if only a colon is given, or if NEW-OWNER is empty, neither the owner nor the group is changed:
# chown : demo.txt

In this example, change the owner of /foo to "root", execute:
# chown root /foo

Likewise, but also change its group to "httpd", enter:
# chown root:httpd /foo

Change the owner of /foo and subfiles to "root", run:
# chown -R root /u

Where,

-R - Recursively change ownership of directories and their contents.


However, if you need to apply conditional file permissions recursively, you need to use combination of the find and chmod command. To find all files in /home/user/demo directory, enter:
$ find /home/user/demo -type f -print

To find all files in /home/user/demo directory with permission 777, enter:
$ find /home/user/demo -type f -perm 777 -print

Finally, apply new permission using the -exec option as follows:
$ find /home/user/demo -type f -perm 777 -print -exec chmod 755 {} \;

To select directories and sub directories use the following syntax:

$ find /var/www/html -type d -perm 777 -print -exec chmod 755 {} \;

Sample Shell Script To Change Permission Recursively


#!/bin/bash
# Purpose: Set correct webserver files and dir permissions
# This script is released under GPL version 2.0 or above
# Set root permission as follows for the Apache / Lighttpd / Nginx DocumentRoot
# + Dirs/Subdirs: read-only and execute to others
# + Files: read-only permission
# Tested on Debian Linux v3/4/5/6 and RHEL v2/3/4/5/6
# -------------------------------------------------------------------------------------------------
_dir="${1:-.}"
_fperm="0444"
_dperm="0445"
_ugperm="root:root"
_chmod="/bin/chmod"
_chown="/bin/chown"
_find="/usr/bin/find"
_xargs="/usr/bin/xargs"

echo "I will change the file permission for webserver dir and files to restrctive read-only mode for \"$_dir\""
read -p "Your current dir is ${PWD}. Are you sure (y / n) ?" ans
if [ "$ans" == "y" ]
then
echo "Changing file onwership to $_ugperm for $_dir..."
$_chown -R "${_ugperm}" "$_dir"

echo "Setting $_fperm permission for $_dir directory...."
$_chmod -R "${_fperm}" "$_dir"

echo "Setting $_dperm permission for $_dir directory...."
$_find "$_dir" -type d -print0 | $_xargs -0 -I {} $_chmod $_dperm {}
fi



You can run this script as follows:
./script /var/www/html/
./script /usr/lib/cgi-bin/