chmod changes the permissions on files and folders. You will use it to make a script executable, protect a private key or fix a web folder after an upload. This guide shows both ways to write permissions, the recursive option and its risks, and how to check that the change did what you meant.
Before you start
- A Linux VPS with Ubuntu 22.04 or 24.04, Debian 12, or AlmaLinux or Rocky Linux 8 or 9.
- An SSH session. You can change permissions on files you own; for other files you need sudo.
- A basic grasp of
rwxand owner, group and others. If that is new, read Linux file permissions explained first.
Numeric mode
Numeric mode sets all permissions at once with three digits: owner, group and others. Each digit is the sum of read (4), write (2) and execute (1).
chmod 644 index.html
chmod 755 deploy.sh
chmod 600 ~/.ssh/id_ed25519
chmod 700 ~/.ssh644: owner reads and writes, everyone else reads. Normal files.755: owner has full rights, others read and run. Folders and scripts.600: only the owner reads and writes. Keys and secrets.700: only the owner can enter. Private folders.
Numeric mode replaces the existing permissions. That makes it predictable: the result is always exactly what you typed.
Symbolic mode
Symbolic mode changes only the bits you name and leaves the rest alone. It has three parts:
- Who:
u(owner),g(group),o(others),a(all). - Action:
+add,-remove,=set exactly. - What:
r,w,x.
Examples:
chmod u+x deploy.sh
chmod g+w shared.txt
chmod o-rwx secrets.env
chmod go= private.key
chmod u=rw,go=r index.htmlu+x: let the owner run the file.g+w: let the group edit.o-rwx: take every right away from others.go=: set group and others to nothing.u=rw,go=r: the same as644, written out.
Make a script executable
The most common chmod of all:
chmod +x backup.sh
./backup.shWithout a "who" letter, +x adds execute for everyone, subject to your umask. Use u+x if only you should run it.
Change permissions recursively
-R applies the change to a folder and everything inside it:
chmod -R g+w /srv/sharedWarning: Recursive changes with numeric modes are risky. chmod -R 644 /var/www/example.com removes x from every folder, so nothing inside can be reached and the site breaks. chmod -R 755 makes every file executable. Never run a recursive chmod on /, /etc or /usr; it can break the system and lock you out of SSH.
To set different values for files and folders, use capital X, which adds execute only to directories and to files that already had it:
chmod -R u=rwX,go=rX /var/www/example.comThis gives folders 755 and normal files 644 in one step. For more control, use find as shown in Set different permissions for files and folders recursively.
Copy permissions from another file
GNU chmod can copy the mode from a reference file:
chmod --reference=index.html about.htmlWhy chmod 777 is wrong
777 lets every user and every process on the server read, change and replace the file. If any app on the server is compromised, the attacker can rewrite your code or plant a backdoor. People use 777 because it makes an error go away, but the real problem is almost always the owner: the web server user is not the owner and is not in the group.
Fix that instead:
sudo chown -R www-data:www-data /var/www/example.com/uploads
chmod 755 /var/www/example.com/uploadsOn AlmaLinux and Rocky the web server user is usually nginx or apache, not www-data.
Useful options
-v: print every file processed.-c: print only files that actually changed. Good for checking a recursive run.--preserve-root: refuse to work on/recursively. GNU chmod does this by default.
Check it works
stat shows the result in both formats:
stat -c '%A %a %n' deploy.sh-rwxr-xr-x 755 deploy.shFor a whole tree, list anything that still has unexpected modes, for example world-writable files:
find /var/www/example.com -perm -o+wNo output means nothing in that tree is writable by everyone.
Troubleshooting
- "Operation not permitted": you are not the owner. Use
sudo, or change the owner first. If root also gets this error, the file may be immutable; check withlsattr. - Script still says "Permission denied" after
chmod +x: the disk may be mounted withnoexec, as/tmpsometimes is. Move the script or run it withbash script.sh. - Site shows 403 after a recursive chmod: folders lost their
xbit. Runchmod -R u=rwX,go=rXon the site folder to restore it. - Permissions change back by themselves: a deploy tool, a control panel or an upload process sets its own modes. Fix the setting there, or adjust the umask.
Next steps
- Change ownership too: chown: change file owner and group.
- Set the defaults for new files: umask: control default permissions.
