Skip to content

Instantly share code, notes, and snippets.

@nilforooshan
Last active November 8, 2023 00:19
Show Gist options
  • Save nilforooshan/6ffb6d6062bdb867d7cb385ff15686e6 to your computer and use it in GitHub Desktop.
Save nilforooshan/6ffb6d6062bdb867d7cb385ff15686e6 to your computer and use it in GitHub Desktop.
sh: chmod and permission

chmod

In a Unix/Linux operating systems, chmod is the command, which may change the access permissions to files and directories.
It works if the user has the right to change the file or directory permission.
When you use ll or ls -l for files, or ls -ld for directories, you will see access permissions as 10 characters before the name of the file or directory. The first character to the left is d for directories, and - for files.
To understand the file permission, consider the following table.

- rwx rwx rwx
user group other

where, r = read, w = write, and x = execute
Any of these characters being - is the lack of that specific permission.
There are two ways of changing file permission.

Symbolic way

Considering u = user, g = group, o = others, and a = all, you can add (+) or deny (-) permissions with different combinations. Examples:

chmod a-x  file.txt  # deny execute permission to all users
chmod g+rw file.txt  # add read & write permissions to group members
chmod g=rw file.txt  # like the previous line

You can use = instead of +, if you have more than one mode in the left or the right side. Example:

chmod ug=rw file.txt # add read & write permissions for user and group members.

To apply changes to a directory and its contents recursively, use option -R.

chmod -R u+w directory # add write permission to the directory (to be able to add/remove files), and all its contents

Numeric way

r w x r w x r w x
400 200 100 40 20 10 4 2 1

The sum of these numbers is 777, which means all permissions given to a file for all users.

chmod 777 file.sh

Summing numbers for specific permissions, you will get the number for the desired permission.
Assume you do not want to give an execute permission for a file to any user, because it is not a program or script, and you want to give read & write permissions to user and group members, and only read permission to others. This is equivalent to: rw-rw-r--
400 + 200 + 0 + 40 + 20 + 0 + 4 + 0 + 0 = 664

chmod 664 file.txt

For not thinking about the right symbolic combination, or number, I wrote the following script, which requires the file or directory name (for example: fileordirname) and the permission mode. If you save the code in a file called (for example) permission.sh, You can run it like this:

. permission.sh rwxrw-r-- fileordirname

Do not forget to give execute permission to the script file itself!

#!/bin/bash
# Check whether enough parameters are given,
if [ $# -lt 2 ] ; then
echo "usage: $0 rwxrwxrwx file/directory name"
echo "Example: $0 rwxrw-r-- myfile"
exit 99
fi
# Check whether the destination file/directory exists.
if [ ! -f $2 ] && [ ! -d $2 ]; then
echo "File/Directory not found!"
exit 99
else
if [ -f $2 ]; then
fileordirectory="file"
else
fileordirectory="directory"
fi
echo "$2 is a $fileordirectory"
fi
# Check whether a correct permission parameter is given.
if [ $(echo "${#1}") != 9 ]; then
echo "Permission code should be 9 characters long."
exit 99
fi
nerror=0
if [ $(echo ${1:0:1}) != "r" ] && [ $(echo ${1:0:1}) != "-" ]; then
echo "The 1st character of the permission should be either r or -"
nerror=$(($nerror+1))
fi
if [ $(echo ${1:1:1}) != "w" ] && [ $(echo ${1:1:1}) != "-" ]; then
echo "The 2nd character of the permission should be either w or -"
nerror=$(($nerror+1))
fi
if [ $(echo ${1:2:1}) != "x" ] && [ $(echo ${1:2:1}) != "-" ]; then
echo "The 3rd character of the permission should be either x or -"
nerror=$(($nerror+1))
fi
if [ $(echo ${1:2:1}) = "-" ] && [ $fileordirectory="directory" ]; then
echo "The 3rd character of the permission for a directory should be x"
nerror=$(($nerror+1))
fi
if [ $(echo ${1:3:1}) != "r" ] && [ $(echo ${1:3:1}) != "-" ]; then
echo "The 4th character of the permission should be either r or -"
nerror=$(($nerror+1))
fi
if [ $(echo ${1:4:1}) != "w" ] && [ $(echo ${1:4:1}) != "-" ]; then
echo "The 5th character of the permission should be either w or -"
nerror=$(($nerror+1))
fi
if [ $(echo ${1:5:1}) != "x" ] && [ $(echo ${1:5:1}) != "-" ]; then
echo "The 6th character of the permission should be either x or -"
nerror=$(($nerror+1))
fi
if [ $(echo ${1:6:1}) != "r" ] && [ $(echo ${1:6:1}) != "-" ]; then
echo "The 7th character of the permission should be either r or -"
nerror=$(($nerror+1))
fi
if [ $(echo ${1:7:1}) != "w" ] && [ $(echo ${1:7:1}) != "-" ]; then
echo "The 8th character of the permission should be either w or -"
nerror=$(($nerror+1))
fi
if [ $(echo ${1:8:1}) != "x" ] && [ $(echo ${1:8:1}) != "-" ]; then
echo "The 9th character of the permission should be either x or -"
nerror=$(($nerror+1))
fi
if [ $nerror -gt 0 ]; then
exit 99
fi
# Translate the permission code to the equivalent integer code
ur=0
uw=0
ux=0
gr=0
gw=0
gx=0
or=0
ow=0
ox=0
if [ $(echo ${1:0:1}) = "r" ]; then
ur=400
fi
if [ $(echo ${1:1:1}) = "w" ]; then
uw=200
fi
if [ $(echo ${1:2:1}) = "x" ]; then
ux=100
fi
if [ $(echo ${1:3:1}) = "r" ]; then
gr=40
fi
if [ $(echo ${1:4:1}) = "w" ]; then
gw=20
fi
if [ $(echo ${1:5:1}) = "x" ]; then
gx=10
fi
if [ $(echo ${1:6:1}) = "r" ]; then
or=4
fi
if [ $(echo ${1:7:1}) = "w" ]; then
ow=2
fi
if [ $(echo ${1:8:1}) = "x" ]; then
ox=1
fi
ichmod=$(($ur+$uw+$ux+$gr+$gw+$gx+$or+$ow+$ox))
# Apply the permission code to the file/directory.
chmod $ichmod $2
# Goodbye message
echo "Permission was changed!"
if [ $fileordirectory = "file" ]; then
echo $(ls -l $2)
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment