In one sentence
chmod is the Unix command that defines who can read, write to, or execute a file, acting as the fundamental access control system for most of the world's servers and developer machines.
The problem it solves
Picture the early days of computing: one person, one machine, one task at a time. On a system like that, file permissions are a solution in search of a problem. If you're the only person who will ever use the computer, who are you protecting the files from? Yourself?
Then came Unix in the late 1960s at Bell Labs. Its revolutionary idea was to be a multi-user, multi-tasking operating system from the ground up. Suddenly, you had multiple programmers logged into the same mainframe computer via different terminals, all working at the same time. This created a new and urgent problem: how do you stop Dennis from accidentally (or "accidentally") deleting Ken's new C compiler? How do you let your project partner read your code but prevent them from changing it? How do you protect the core operating system files from a bumbling intern?
The solution was a beautifully simple and robust system of ownership and permissions baked into the file system itself. Every file and directory would have an owner, belong to a group, and have a specific set of permissions for three classes of users: the owner, members of the group, and everyone else.
The command to "change the mode" of a file—that is, to modify these permissions—was named chmod. It became the universal tool for system administrators and users to declare, "This file is mine, and here are the rules for interacting with it." It solved the multi-user chaos problem so effectively that the same core model is still used today on virtually every Linux server, macOS machine, Android phone, and IoT device on the planet.
How it works under the hood
At its heart, the chmod system is a 3x3 grid of rules, with a few special flags for flair. To get it, you need to understand the three types of permissions and the three classes of users they can apply to.
The Three Permissions: Read, Write, Execute
Everything revolves around three basic actions you can perform on a file or directory. They're represented by the letters r, w, and x.
- Read (
r): The ability to open and view the contents of a file. - Write (
w): The ability to modify, change, or delete the contents of a file. - Execute (
x): The ability to run the file as a program or script.
But here's the first "gotcha": these permissions mean slightly different things for a directory. This is a super common point of confusion.
| Permission | On a File | On a Directory |
|---|---|---|
Read (r) |
Can see file's contents | Can list the names of files in the directory (ls) |
Write (w) |
Can change file's contents | Can create, rename, or delete files within the directory |
Execute (x) |
Can run the file | Can enter the directory (cd) and access files inside it |
Think about that last one. If a directory doesn't have execute permission for you, you can't cd into it, even if you can see its contents! You need x to pass through the directory's "door."
The Three User Classes: Owner, Group, Others
Unix permissions aren't universal; they're assigned to specific categories of users.
- Owner (
u): A single user who owns the file. Typically, this is the person who created it. The owner has the most control. - Group (
g): Every file belongs to a group. This allows the owner to share access with specific team members. For example, all files for "Project Apollo" could belong to theapollo-devsgroup. - Others (
o): Literally everyone else. Any user on the system who is not the owner and does not belong to the file's group.
When you see a permission string like rwxr-xr--, it's actually three sets of rwx permissions mashed together for Owner, Group, and Others, in that order.
rwx: The Owner can read, write, and execute.r-x: The Group can read and execute, but not write.r--: Others can only read.
The Two Notations: Symbolic vs. Octal
There are two ways to tell chmod what you want, and developers are forever translating between them.
1. Symbolic Notation (the "friendly" way)
Symbolic notation uses the letters we've already learned (r, w, x and u, g, o, a where a means "all"). You use + to add a permission, - to remove it, and = to set it exactly.
# Give the owner execute permission
$ chmod u+x my_script.sh
# Remove write permission for the group and others
$ chmod go-w sensitive_data.txt
# Set permissions exactly: owner can read/write, group can read, others have no access
$ chmod u=rw,g=r,o= config.yml
This is great for making small, targeted changes.
2. Octal Notation (the "nerdy" way)
Octal is faster, more common in scripts, and based on binary. Each permission (r, w, x) is a bit in a 3-bit number.
r(read) is the first bit, with a value of 4.w(write) is the second bit, with a value of 2.x(execute) is the third bit, with a value of 1.
You add the numbers together for the permissions you want.
| Number | Binary (rwx) |
Permissions Granted |
|---|---|---|
| 0 | 000 (---) |
None |
| 1 | 001 (--x) |
Execute |
| 2 | 010 (-w-) |
Write |
| 3 | 011 (-wx) |
Write and execute |
| 4 | 100 (r--) |
Read |
| 5 | 101 (r-x) |
Read and execute |
| 6 | 110 (rw-) |
Read and write |
| 7 | 111 (rwx) |
Read, write, execute |
A three-digit octal code like 755 represents the permissions for Owner, Group, and Others.
chmod 755 my_script.sh means:
- Owner:
7(rwx) - Read, write, and execute. - Group:
5(r-x) - Read and execute. - Others:
5(r-x) - Read and execute.
This is a very common permission for executable scripts that are safe for others to run. A common permission for a file is 644 (owner can read/write, everyone else can only read).
The Special Guests: SUID, SGID, and the Sticky Bit
Beyond the basic rwx, there are three special modes, represented by a fourth octal digit at the beginning (e.g., chmod 4755).
- SUID (Set User ID) - Octal
4: When an executable file with this bit is run, it executes with the permissions of the file owner, not the user who ran it. The classic example is thepasswdcommand, which needs to modify the protected/etc/shadowfile. Thepasswdexecutable is owned byrootand has the SUID bit set, so when a normal user runs it, it temporarily gains root privileges just for that one operation. It's powerful but dangerous. - SGID (Set Group ID) - Octal
2: Similar to SUID, but an executable runs with the file's group identity. More usefully, when set on a directory, any new file or directory created inside it will automatically inherit the parent directory's group, not the creating user's primary group. This is essential for shared project folders. - Sticky Bit - Octal
1: This has a weird history, but today it's almost exclusively used on directories. When a directory has the sticky bit (like the system's/tmpfolder), all users can create files in it, but a user can only delete or rename files that they themselves own. It prevents people from messing with each other's stuff in a shared space.
Real-world stories
The Case of the Un-runnable Script
A junior developer, Alex, writes a brilliant shell script to automate server deployment. He commits deploy.sh to Git. On the production server, he clones the repository, types ./deploy.sh, and hits Enter. The response: bash: ./deploy.sh: Permission denied. Panic. Did he break the server? A senior dev calmly types ls -l deploy.sh and shows him the output: -rw-r--r--. The file had read and write permissions, but not execute (x). Git doesn't preserve execute permissions by default. A quick chmod +x deploy.sh later, the script ran perfectly.
Lesson: Files, especially from sources like Git or zip archives, are not executable by default. You must explicitly grant permission to run them.
The Shared Project Folder Nightmare
A design team and a development team needed to share assets in a folder on a Linux server: /data/project-x. The sysadmin put everyone in the project-x-team group and gave the group write access to the folder. But chaos ensued. When a designer uploaded a file, it was owned by designer:designers, and the devs couldn't modify it. When a dev created a sub-folder, it was owned by dev:developers, and the designers couldn't add files to it. Everyone was constantly asking the sysadmin to fix permissions. The solution? The admin ran chmod g+s /data/project-x. This set the SGID bit on the directory. From then on, every new file and folder created inside /data/project-x automatically inherited the project-x-team group. Harmony was restored.
Lesson: SGID on a directory is the correct, non-hacky way to manage shared group folders.
The Public Website Security Hole
A freelance web developer launched a simple PHP website for a client. For convenience, he left the database configuration file, config.inc.php, in the same directory as the homepage. The file contained the database username and password in plain text. Its permissions were the default 644 (-rw-r--r--), which meant the web server's user could read it (good), but so could anyone on the planet who guessed the URL. A security scanner found the file, and the attacker downloaded the database credentials. The fix should have been chmod 600 config.inc.php, making it readable only by the owner (the web server process).
Lesson: Never assume default permissions are secure. Sensitive files like configs and private keys should be locked down to be as restrictive as possible.
Common mistakes and traps
- The
chmod 777sledgehammer. When frustrated, many are tempted to runchmod -R 777 .on a directory. This recursively gives everyone permission to read, write, and execute everything. It's a catastrophic security vulnerability and the digital equivalent of taking the doors off your house and leaving a "Free Stuff Inside" sign on the lawn. Don't do it. - Forgetting directory
xpermission. You can haverpermission on a file but be unable to access it because you don't havexpermission on one of the parent directories in its path. You need execute permission on all directories you wish to traverse. - The
umaskmystery. Ever wonder why new files you create are644and not777? That's yourumaskat work. Aumaskis a "mask" that your shell applies, removing permissions from files and directories as they're created. A commonumaskof022removes the "write" permission for Group and Others, turning a default666into644. - Thinking
chmod +xis the same aschmod 755. It's not.chmod 755 my_filesets the permissions absolutely.chmod +x my_fileadds the execute bit for any user class (owner, group, other) that already has the read bit, without changing any other bits. Symbolic mode is relative; octal mode is absolute.
Why it belongs on your radar
If you touch a non-Windows command line, you need to understand chmod. It's not optional. This knowledge is crucial when:
- Deploying any application to a Linux server.
- Writing scripts (Shell, Python, Node.js) that need to be executed.
- Working with Git, which has its own ideas about file permissions.
- Setting up file shares or collaborative environments.
- Hardening a server's security by restricting access to sensitive files.
- Using Docker, where file permissions inside the container are paramount.
chmod is one of the first and most fundamental commands that separates a casual user from a true system operator or developer. Understanding it is a rite of passage into controlling the machine, not just using it.
Go deeper
- Wikipedia: chmod - A great high-level overview of the command, its history, and its different notations.
- Wikipedia: File-system permissions - A broader look at the concepts of DAC, ACLs, and the symbolic/octal notation across systems.
- The Linux man-pages project: chmod(1) - The canonical, technical reference for the
chmodcommand on Linux. Dense but authoritative. - The Open Group Base Specifications (POSIX): chmod - The actual standard that defines how
chmodmust behave on any POSIX-compliant system (like macOS and Linux). - ArchWiki: File permissions and attributes - A very practical and well-maintained guide from the Arch Linux community, covering
chmod,chown, and special attributes.