This is one of the oldest commands as it has been around since the first version of Unix that was released in 1971. The GNU version was written by David MacKenzie, the same author as head, tail, and many others that I haven’t covered yet. chmod stands for change mode. What some may consider to be file permissions were considered modes, and are still referenced as such. I recommend checking out the man page for chmod from the Unix1 to see the differences between now and 1971. The current man page still has this summary for it:

change file mode bits – man 1 chmod (GNU version)

For this article I’ll be referring to them as permissions.

A Brief Overview of Linux File Permissions

If you have a grasp on Linux file permissions, then go ahead and jump to the examples. However, if you feel like you need a refresher, or that picture at the top doesn’t make sense to you, perhaps read on.

Let’s start with a simple example. Here’s a file on my system called deploy.sh. It’s how I get my blog from my local machine to the server >.> Running a quick ls -l will show us the permissions of this file.

ls -lh deploy.sh
-rwxr-xr--  1 drt  staff    76B Feb 23 18:52 deploy.sh

The first section is the permissions of the file or file mode. Next is the number of links, in this case 1, but don’t worry about this, not important for this discussion. Following that is the owner name, and the group name. These are important, as they each have their own permissions for files.

Now, let’s break down the permissions section. It’s broken up into 4 different sections. The first character is the special permissions flag. The - shows that there a no special permissions on this file. However, a few you will see is a d for directory, l is for symbolic links, s for the setuid/setguid permission, and t for the sticky bit. I won’t go into nitty-gritty of these, but I hope the first two are self explanatory.

The remaining nine characters are broken up into three sets of three permissions for the following groups: user, group, all respectively. The three permissions available are read, write, and execute, represented by r, w, x.

Using the example above, the deploy.sh file has the following group permissions

Section Value Permissions Meaning
user drt rwx read, write, execute
group staff r-x read, execute
all [none] as this is for other users on the system that are not drt and not part of the staff group r-- read

The chmod application also allows has an octal representation for the permissions. Think of this as three bits, where flipping on the bit, turns on that permission. For example, from left to right, flipping on the first bit (100) has an octal representation of 4. Flipping only the middle bit (010) has a value of 2, and finally the last bit (001) has a value of 1. Therefore, setting a value of 6 (110) gives the permissions read and write. Check out the table below for a better reference.

file permissions description octal binary
-rwx read, write, execute 7 111
-rw- read, write 6 110
-r-x read, execute 5 101
-r-- read 4 100
--wx write, execute 3 011
--w- write 2 010
---x execute 1 001
---- nothing 0 000

chmod Permission Groups

The chmod command allows you to set permissions for each section. You can use the syntax below.

syntax group name
u Owner
g Group
o Others
a All users

For each group, there are three operators:

operator meaning
+ add permission
- remove permission
= set the permissions to exactly what follows


A common use case you should familiarize yourself with is adding the execution permission to a script you’re writing.

chmod +x myscript.sh
This applies the execute permission to all sections: user, group, other (the same as all). Queue quip to look at picture at top. So you might be wondering, what’s the difference between that and chmod a+x myscript.sh? there isn’t any.

Before we dive into the rest of the examples I want to make one more quick note. GNU chmod does have a few flags that I wont be covering. The only one I actually use is -R which is for recursive. This changes the permissions on the files and directories going down the tree. This is important to understand because there are times where you’ll want to change permissions of the files and not the directories. If you recursivly remove the execute permissions down a tree, you will remove the execute permission for the directories. You might be thinking: how can you execute a directory?? well without the x permission on a directory, you are not able to cd into it, or really do anything. It’s why the umask is usually set to 022 giving a default of execute permissions on new directories. This is a common chmod gotcha, use find -type f -exec chmod 644 {} \; instead.


Here’s a few examples using the symbolic methods, and the file we’ll be working with:

ls -l hello.py
-rw-----wx  1 drt  staff  222 Mar 29 16:57 hello.py
cat hello.py
#!/usr/bin/env python

import hashlib

USERNAME = "drt"
PASSWORD = "(p@ssw0rD)"

passwd = hashlib.sha1(PASSWORD).hexdigest()

print("here's the information in username:hash format")
print("{}:{}".format(USERNAME, passwd))
Obviously this is a very sensitive file <.< We need to go through and update the permissions accordingly.

First off let’s update the other permissions. They have the permission to write and to execute, that’s no good. Let’s remove the permissions, so others have no access to this file.

chmod o-xw hello.py
ls -l hello.py
-rw-------  1 drt  staff  222 Mar 29 16:57 hello.py

Looking good! Now let’s adjust the group permissions. We need to have the group be able to read the file in case they need the password, and we want them to be able to execute the file like ./hello.py. Let’s not add the write permission, as that might lead to someone being a jerk.

chmod g+rx hello.py
ls -l hello.py
-rw-r-x---  1 drt  staff  222 Mar 29 16:57 hello.py

Finally, lets make it so the user has all the permissions. As it’s their file, this make sense as we want it to be executable as well. Notice that even though the user has read and write permissions, because we’re using the = operand, we still need to provide all the permissions we want user to have.

chmod u=rwx hello.py
ls -l hello.py
-rwxr-x---  1 drt  staff  222 Mar 29 16:57 hello.py

Just for fun, lets combine all of these into a single command.

chmod o-wx,g+rx,u=rwx hello.py
ls -l hello.py
-rwxr-x---  1 drt  staff  222 Mar 29 16:57 hello.py

You even have the option to use + and - in the same statement like this.

chmod o-rwx,g+x-rw,u+x hello.py
ls -l hello.py
-rwx--x---  1 drt  staff  222 Mar 29 16:57 hello.py


Personally, using the numbers makes the most sense to me, but you may feel differently. These are the exact same scenarios as above, except it uses the numerical format. If you want a fun exercise, go back to the symbolic examples and try to do them using octal sets.

Removing other.

chmod 600 hello.py
ls -l hello.py
-rw-------  1 drt  staff  222 Mar 29 16:57 hello.py

Adding group.

chmod 650 hello.py
ls -l hello.py
-rw-r-x---  1 drt  staff  222 Mar 29 16:57 hello.py

Make user have all permissions.

chmod 750 hello.py
ls -l hello.py
-rwxr-x---  1 drt  staff  222 Mar 29 16:57 hello.py

As an added bonus, let’s add the sticky bit to our file!

chmod 1741 hello.py
ls -l hello.py
-rwxr----t  1 drt  staff  222 Mar 29 16:57 hello.py

Why You Shouldn’t chmod 777

With your new knowledge about Linux file permissions, can you think why using chmod 777 is a bad idea? This gives anyone on the system access to that file or directory. Imagine you have a web server running at /var/www/my-site and it (and its subdirectories) have the permissions of 777. Even if the web server user/group is the owner, anyone can still modify those files. Users with malicious intent see this as a gold mine. They are able to modify, add, delete whatever they want. If you’ve ever ran phpBB way back when, you might remember having to do chmod -R 777 phpbb and hating yourself. Blindly using 777 makes the Linux access control list null and void. Why have users or groups? When you use chomd just remember to think, who really needs access. It’s easier to add permissions, than to remove after its too late.