chmod Cheatsheet - Linux File Permission Reference
A permission failure usually announces itself as one line - Permission denied - while the real cause might be a wrong bit order, a directory missing execute, a mismatched group, or an umask silently rewriting the defaults of every new file. Once owner, group and others are understood as a triple of permission sets, plus the SUID, SGID and sticky special bits, the nine characters printed by ls -l stop being runes and become an expression you can do arithmetic on. This sheet shows numeric and symbolic modes side by side for the same permissions, states which position each one lands on, and gives the special bits their own section because they do not change who may read or write - they change how permission is granted. SUID makes a program run as the file owner, SGID makes new files in a directory inherit its group, and sticky restricts deletion to the owner. Reach for it when chmod +x still fails, a log directory refuses writes, SSH rejects a private key, or a container reports owner 1001. It is less expressive than ACLs, but it is the most portable form and the only one Docker COPY and deploy scripts honour.
Typical Use Case
For developers and operators managing Linux file permissions. The core is three things: numeric mode where r=4, w=2 and x=1 add up, symbolic mode using u/g/o/a to add and remove, and the fact that x on a directory means something entirely different from x on a file — on a directory it means you may enter it, and without it cd fails even when r is set. This sheet covers numeric and symbolic modes, the special permissions (SUID, SGID, Sticky), common combinations and umask, with the two extremes worth avoiding called out: 777 and 600.
Permission Bits 6
r (read)w (write)x (execute)- (no permission)u g oaNumeric Mode 6
chmod 755 filechmod 644 filechmod 700 filechmod 600 filechmod 777 filechmod 750 dirSymbolic Mode 6
chmod u+x filechmod go-w filechmod a+r filechmod u=rw,go=r filechmod +x script.shchmod -R 755 dir/Special Permissions 6
chmod u+s file (4755)chmod g+s dir (2755)chmod +t dir (1777)chmod 4755 filechmod 2755 dirchmod 1777 dirCommon Patterns 6
644755600640700750Related Commands 7
chmod --reference=file1 file2chown user filechown user:group filechown -R user:group dir/chgrp group fileumask 022umask -SParameter matrix
| Parameter | Effect | Example |
|---|---|---|
r / w / x | Read 4 / write 2 / execute 1 | rwx = 4+2+1 = 7 |
u / g / o / a | Owner / group / others / all | a is equivalent to ugo |
755 | Standard permission for executable files and directories | chmod 755 script.sh |
644 | Regular files: owner read/write, others read-only | chmod 644 config.yaml |
600 | Owner read/write only, the standard permission for private keys | chmod 600 ~/.ssh/id_rsa |
640 | Config files: owner read/write, group read-only | chmod 640 /etc/shadow |
700 / 750 | Private directory / shared directory | chmod 750 /opt/app |
u+x / go-w / a+r | Symbolic mode to add or remove a single permission | chmod u+x entrypoint.sh |
u=rw,go=r | Symbolic mode to set directly (equivalent to overwrite) | chmod u=rw,go=r file |
chmod -R | Recursively change everything under the directory | chmod -R 755 dist/ |
u+s (4755) | SUID: runs as the owner when executed | chmod 4755 /usr/bin/ping |
g+s (2755) | SGID: new files in the directory inherit the group | chmod 2755 /shared |
+t (1777) | Sticky: others can delete only their own files | chmod 1777 /tmp |
--reference | Set permissions by referencing another file | chmod --reference=file1 file2 |
umask | Default permission mask for new files | umask 022 |
Common pitfalls
SymptomThe directory is already chmod 755, but cd into it reports Permission denied.
CauseWithout the x permission you cannot enter the directory, even with the r permission (r only affects whether the contents can be listed).
FixAdd the execute bit: chmod u+x dir (directories usually need 755).
SymptomAfter chmod 777 the service instead fails to start.
CauseFull permissions make security modules (such as SELinux and AppArmor) and some programs refuse to execute; it also increases tampering risk.
FixFollow least privilege and change back to 755 or 640; when a program cannot execute, check the SELinux log first instead of adding permissions.
SymptomSSH reports UNPROTECTED PRIVATE KEY FILE and refuses to log in.
CauseThe private key permissions are too broad (any permission for group or other is rejected).
Fixchmod 600 ~/.ssh/id_rsa; the directory also needs 700.
SymptomAfter chmod -R the whole directory tree's permissions are messed up and hard to restore.
CauseRecursion unifies permissions that should have differed (for example changing a 600 private key to 644).
FixBack up before recursing; use --reference or set permissions directory by directory to avoid indiscriminate -R.
SymptomAfter adding +x to the script, ./script.sh still reports Permission denied.
CauseThe interpreter declaration (shebang) is missing, so the kernel does not know what to execute it with.
FixAdd #!/bin/bash to the first line of the script and make sure the interpreter path exists.
Symptomchown changed the owner but the program still cannot access it.
CausePermissions are constrained by three classes at once, owner, group, and others; changing the owner does not necessarily loosen the group or other limits.
FixAfter chown user:group file, confirm the permission bits with ls -l (check the rwx combination) and add chmod if needed.
SymptomNewly created scripts have no execute permission by default and must all be added during batch deployment.
Causeumask only affects the read/write bits of new files (usually 644); the execute bit must be set explicitly.
FixExplicitly chmod +x in the deployment script, or use install -m 755 to set the permission in one step.
Troubleshooting
1View the current permissions and decode them bit by bit
ls -l fileTen characters: the first is the file type, and the next nine are the rwx of u/g/o in order.
2Fix private key permissions
chmod 600 ~/.ssh/id_rsa && chmod 700 ~/.sshThe private key must be 600 and the directory must be 700, otherwise ssh will refuse to use them.
3Set permissions by referencing an existing file
chmod --reference=template.conf new.confSafer than writing numbers by hand, avoiding making a file public that should have been private.
4Confirm the default permission mask
umask -SThe symbolic form is more intuitive; umask 022 corresponds to 644 for new files and 755 for directories.
5Set permissions on a directory tree in bulk
chmod -R 755 dist/Use it only for output directories with definitively uniform permissions; never -R 755 a directory of private files.
Command Examples
Make a script executable and run it
chmod +x deploy.sh
./deploy.shchmod +x is equivalent to adding the execute bit for all three classes of users. When ugo is omitted it defaults to a. Note that scripts edited on Windows carry CRLF and report bad interpreter; convert them with dos2unix.
Lock down private key permissions
chmod 600 ~/.ssh/id_ed25519SSH refuses private keys that are readable or writable by group or other and reports UNPROTECTED PRIVATE KEY FILE. 600 is the only correct value for a private key.
Copy permissions from a reference file
chmod --reference=deploy-prod.sh deploy-staging.sh
stat -c "%a %n" deploy-*.sh--reference avoids retyping numbers from memory, especially when aligning permissions in bulk across multiple machines. After changing, confirm the actual effective value with stat.
Output
755 deploy-prod.sh 755 deploy-staging.sh
Common Pitfalls
- chmod 777 lets any user modify the file, so once anything on the host is compromised that path has no protection — avoid it.
- Private keys must be 600; SSH refuses to use a key readable by group or others.
- A 0 in numeric mode clears those permissions, so chmod 000 makes a file inaccessible; recovery requires root.
- A CRLF script edited on Windows fails with bad interpreter after chmod +x — that is a line-ending problem, not a permission one.
- Changing permissions is not the same as changing ownership; combine with chown when access, not just mode, is the issue.
Tips
- Numeric mode: r=4, w=2, x=1; sum them for the value (e.g. rwx = 4+2+1 = 7).
- A directory's x means you can enter it (cd); without x, even r won't let you in.
- SUID has no effect on scripts (only on binaries) and is a security risk — use with caution.
FAQ
What do 755, 644 and 600 mean?
Numeric mode splits permissions into r=4, w=2, x=1 across owner, group and others. 755 = rwxr-xr-x gives the owner full access and read/execute to everyone else — typical for executables and directories. 644 = rw-r--r-- leaves only the owner able to write, good for ordinary files. 600 = rw------- is owner-only read/write, the right choice for private keys such as your SSH key.
Why does my script still not run after chmod +x?
Two usual causes. First, line endings: a script edited on Windows has CRLF, which produces a bad interpreter error — convert with dos2unix or sed -i 's/ $//' script.sh. Second, the shebang path may not exist: check that the #! line matches a real interpreter on the machine. Apply chmod +x and then run it.
When do I need SUID, SGID or the sticky bit?
SUID (u+s, e.g. chmod 4755) runs a program with the file owner's identity — passwd editing /etc/shadow is the classic example. SGID (g+s, e.g. chmod 2755 on a directory) makes new files inherit the directory's group, which suits shared team directories. The sticky bit (+t, as on /tmp at 1777) lets only a file's owner delete it, preventing accidental cross-deletion.
What is the difference between chmod and chown?
chmod changes permission bits — who can read, write or execute. chown changes the owner and group. To let a colleague read a file, chmod 644 or chmod g+r is enough; you only need chown user file when handing management to someone else. In practice prefer permissions, since changing ownership usually has a wider blast radius.
Is chmod 777 ever acceptable as a shortcut?
No. 777 lets any user modify the file, so any compromised process can replace it — you have effectively given up control of that path. Use 755 for executables, 644 for read-only files and 600 for anything sensitive like private keys. If permissions still look wrong, check whether SELinux or the umask is the real cause before loosening bits further.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Jul 21, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us