Short answer: chmod MODE FILE sets who can read, write and execute a file. The mode is three digits (chmod 755 script.sh) or a symbolic change (chmod +x script.sh), each digit or letter covering the owner, the group and everyone else in that order. Below: what the common modes mean, recursive chmod without breaking directories, and why chmod 777 is almost always the wrong fix.
Octal mode: the three digits
Each digit is read, write and execute added up — read = 4, write = 2, execute = 1 — for the owner, the group, then everyone else:
| Value | Permissions | Meaning |
|---|---|---|
| 7 | rwx | 4 + 2 + 1 — read, write, execute |
| 6 | rw- | 4 + 2 — read, write |
| 5 | r-x | 4 + 1 — read, execute |
| 4 | r-- | 4 — read only |
| 0 | --- | no permissions at all |
| chmod | Symbolic | Use it for |
|---|---|---|
| 644 | rw-r--r-- | Ordinary files: HTML, images, configs |
| 755 | rwxr-xr-x | Directories, and scripts or binaries anyone may run |
| 700 | rwx------ | Private scripts and directories — only the owner touches it |
| 600 | rw------- | Private files — SSH keys, credentials, .env files |
| 777 | rwxrwxrwx | Almost never the right answer — see below |
chmod 755 deploy.sh
chmod 644 index.html
chmod 600 ~/.ssh/id_ed25519To go the other way — tick the permissions you want and read off the octal number, or paste a mode and see what it means — the chmod calculator does both, including setuid, setgid and the sticky bit below.
Symbolic mode: +x, -w, u/g/o
Symbolic mode changes permissions relative to what a file already has, rather than replacing the mode outright — the most common reason to reach for it is making a script executable without touching its read and write bits:
| Command | What it does |
|---|---|
| chmod +x file | Add execute for owner, group and others |
| chmod -x file | Remove execute for everyone |
| chmod u+x file | Add execute for the owner only |
| chmod g+w file | Add write for the group |
| chmod o-rwx file | Remove all permissions for everyone else |
| chmod a+r file | Add read for everyone (a = owner + group + others) |
| chmod u=rwx,g=rx,o=rx file | Set exact permissions per class — equivalent to 755 |
u is the owner (user), g the group, o everyone else, and a all three together. + adds a permission without touching the others, - removes one, and = sets the class to exactly what follows, clearing anything not listed.
Recursive chmod: -R, and doing it properly
chmod -R 755 /var/www/siteSet directories and files to different modes in one pass with find instead:
find /var/www/site -type d -exec chmod 755 {} +
find /var/www/site -type f -exec chmod 644 {} +A directory needs its own execute bit before anything can cd into it or open a file inside it by name, which is why 755 — not 644 — is the baseline for directories even when nothing in them should be run as a program.
Why chmod 777 is (almost) always wrong
777 gives read, write and execute to the owner, the group, and every other account on the system — including a web server’s user if another site on the same machine is compromised, or any process that can reach the file at all. On a directory it also lets anyone create or delete files inside it, not only change the ones already there.
Almost every “just chmod 777 it” fix found online is really an ownership problem in disguise: a file owned by root that a service running as www-data needs to write to. The fix is chown, not a wide-open mode:
sudo chown www-data:www-data /var/www/site/uploads
sudo chmod 755 /var/www/site/uploads # or 775 if the group also needs write accessA 403 Forbidden from nginx is the error that most often tempts people toward 777 — it is almost always this same ownership mismatch, not a missing permission bit.
Permission denied despite the right mode
- Every parent directory needs execute, too.
chmod 755on the file itself does nothing if/var/www/siteis700— a process needs execute on every directory in the path to reach the file, not only on the file. - SELinux or AppArmor can block access a chmod mode allows — on Rocky and AlmaLinux,
ls -Zshows the SELinux context, andrestorecon -Rv pathresets it to the distribution’s default for that location. - A mounted filesystem can ignore chmod outright — a FAT32 or network share mounted without permission options takes whatever mode was given at mount time, not what you set afterward.
If a command itself refuses to run after chmod +x, see bash: Permission denied — the cause is usually one of the three above, or a noexec mount.
SSH refuses a key with the wrong mode for an entirely different reason — sshd will not trust a private key or .ssh directory that other accounts can write to; see Permission denied (publickey).
Frequently asked
What does chmod 777 do, and why is it a bad idea?
It gives read, write and execute to the owner, the group and every other account on the system — including a web server's own user if another site on the same machine is compromised. Almost every case where 777 'fixes' something is really an ownership problem: chown to the right user and keep the mode at 644 or 755.
What is the difference between chmod 644 and 755?
644 (rw-r--r--) lets the owner read and write and everyone else read — the normal mode for files. 755 (rwxr-xr-x) adds execute for everyone, which directories need to be entered and scripts need to be run.
How do I chmod recursively without making every file executable?
chmod -R applies the same mode to everything, files included. Use find instead: find path -type d -exec chmod 755 {} + for directories, find path -type f -exec chmod 644 {} + for files.
Why does chmod +x not work?
It usually does — check with ls -l that the x actually appears. If the script still will not run, the more common cause is a missing or wrong shebang line (#!/bin/bash) or trying to run it without the leading ./ (./script.sh).