Cheat Sheet

chmod Cheat Sheet

chmod changes who can read, write, and execute a file on Linux and macOS. This sheet covers the octal numbers, symbolic syntax, recursive changes, SSH key permissions, the special bits, and the chown and umask companions.

Last updated September 11, 2026

Octal Numbers

Three digits: owner, group, others. Each digit adds read 4, write 2, execute 1. Decode or build any mode with the chmod calculator.

DigitMeaning
rwx: read, write, execute
rw-: read and write
r-x: read and execute
r--: read only
---: nothing

The modes that cover almost every real case:

CommandWhen to use it
Directories, scripts, binaries: owner full, others read and enter
Normal files: owner edits, others read
Private files: owner only (SSH keys, credentials)
Private directories: owner only
Read-only key files (AWS .pem)
Group-writable directory for a team
Group-writable file
Almost never right; see Web Server Permissions below

Symbolic Syntax

Who ( owner, group, others, all), then add, remove, set exactly, then , , .

CommandWhat it does
Owner may execute
Everyone may execute (the usual "make it runnable")
Remove write from group and others
Everyone gets exactly read, nothing else
Same as 755, spelled out
Let the group write
Others get nothing
Capital X: execute on directories only (see Recursive)

Make a File Executable

CommandWhat it does
Make a script executable
Run it (the is required outside PATH)
Confirm:

The first line of the script should name its interpreter ( or ), or you will get or the wrong shell.

Recursive Changes

hits every file and directory, and one number is usually wrong for one of them: makes directories unenterable, makes every file executable.

CommandWhat it does
Everything 755 (fine for a tree of scripts, wrong for docs)
Directories to 755 only
Files to 644 only
One pass: X sets execute on dirs (and already-executable files) only

More find patterns in the find cheat sheet.

Multiple Files and Wildcards

The shell expands the wildcard before chmod runs, so reaches chmod as a plain list of filenames.

CommandWhat it does
Several named files in one call
Every in the current directory only
The top level of dir, not its subdirectories
Hidden files (plain also matches and )
Copy another file's mode instead of naming one (GNU)
When the list is long enough to hit

Directories vs Files

The same three letters mean different things on a directory.

BitOn a fileOn a directory
Read the contentsList the file names
Modify the contentsCreate, rename, delete entries inside
Run it as a programEnter it () and reach files inside

Deleting a file needs on the directory, not on the file. A directory without blocks access to everything under it no matter what the files say.

A symlink has no useful mode of its own on Linux: access is decided by the target.

CommandWhat it does
Follows the link and changes the target
Changes the link itself (macOS/BSD only; GNU chmod has no )
Symlinks met during the walk are skipped, never followed
Links always read ; Linux ignores that mode

means the link points at a path that no longer exists.

setuid, setgid, Sticky Bit

A fourth leading digit, or / in symbolic form.

CommandWhat it does
setuid: runs as the file's owner (how edits /etc/shadow)
setgid on a directory: new files inherit its group
Sticky bit: anyone writes, only owners delete their own files
setuid, symbolic
setgid, symbolic
Sticky bit, symbolic
List every setuid binary (audit)

In , setuid/setgid show as in the owner/group execute slot and the sticky bit as at the end ( on /tmp). A capital or means the bit is set but execute is missing, which is usually a mistake.

SSH Key Permissions

OpenSSH checks permissions before it will use a key. A private key that group or others can read is refused outright with , and on the server (on by default) makes sshd ignore when the home directory, , or the file itself is group- or world-writable. Full command list in the SSH cheat sheet.

CommandWhat it does
The .ssh directory, both ends
Private key (fixes "UNPROTECTED PRIVATE KEY")
Public key
On the server; ignored if too open
Client config
Host key store (600 is fine too)
AWS-style read-only key
Home directory, when a shared box left it group-writable

The server side is silent about all of this: sshd logs the reason locally and sends the client nothing, so a permissions problem on the server reaches you only as Permission denied (publickey).

Reading ls -l Output

-rwxr-xr--  1 alice developers  4096 Sep  5 10:30 deploy.sh

Type, then three triads: owner , group , others . That file is 754. Paste any string into the chmod calculator to get the number back.

First characterMeaning
Regular file
Directory
Symlink
CommandWhat it does
Long listing with permissions
The directory itself, not its contents
Show the octal mode (GNU/Linux)
Show the octal mode (macOS)

A trailing means ACLs are set (see below); on macOS means extended attributes.

ACLs

When owner, group, and others cannot express who needs access, an ACL adds per-user entries on top of the mode bits. marks a file that has one with a trailing .

CommandWhat it does
Show the ACL behind that
Grant one extra user, without touching the group
Same for a group
Remove that entry
Strip the ACL, back to plain mode bits
Default ACL: new files inside inherit it

Running chmod on a file with an ACL rewrites the ACL mask, which can quietly cut the extra entries down. Check with after any chmod on an ACL'd path.

chown and chgrp

chmod changes what the owner, group, and others are allowed to do. chown changes who the owner and group are, and needs root. When a service cannot write a path, chown is almost always the right half of the pair.

CommandWhat it does
Change the owner
Owner and group at once
Recursive, the web-uploads fix
Group only (works without root for your own files)
See current owner and group

umask

umask decides the default mode of new files: files start from 666 and directories from 777, minus the mask.

CommandWhat it does
Show the current mask (022 is the common default)
New files 644, new directories 755
New files 600, new directories 700 (private by default)
Group-writable: files 664, directories 775

Set it in or to make it stick.

Web Server Permissions

The convention on Debian/Ubuntu (nginx and Apache run as ; on RHEL it is or ):

CommandWhat it does
Server owns its files
Directories 755
Files 644
Writable dirs: group-writable, with the right group

When an app "needs" 777 to work, the real problem is ownership: the process user cannot write because it does not own the path. to the process user (or share a group) and keep 755/644. 777 hands write access to every account on the box.

Options and Flags

OptionWhat it does
Recursive
Report every file touched
Report only files that actually changed
Silence error messages
Copy another file's mode (GNU)
Change a symlink itself instead of its target (macOS/BSD)

Fixing chmod Errors

ErrorFix
You gave a mode and no file. chmod needs both:
Octal digits only run 0-7; symbolic modes must read
(you own it, still fails)Immutable flag: then (Linux); then (macOS)
on macOS system pathsSIP protects them; you cannot chmod /System and friends
You do not own the file: , or fix ownership with chown
/ You are in CMD or PowerShell, not a Unix shell; use , or run it inside WSL
An SMB, NFS, or NAS mount with no POSIX ACL support; set permissions on the share instead
chmod "works" but nothing changesFAT32/exFAT/NTFS mounts have no Unix permissions; set them at mount time with /
Remount first:

macOS and Windows

EnvironmentSituation
macOSSame chmod (BSD flavour); everything above works, flags differ as shown
Windows (native)No chmod; is the closest equivalent
Windows (WSL, Git Bash)chmod works on Linux paths; on it is a no-op until you enable metadata
Git anywhereGit tracks only the execute bit; sets it in the index

To make chmod stick on Windows drives in WSL, add this and restart WSL with :

# /etc/wsl.conf
[automount]
options = "metadata,umask=22,fmask=11"

Gotchas

  • Modes survive reboots but not every copy. without , most unzip tools, and without reset the mode at the destination, and git records only the execute bit.
  • chmod updates a file's ctime, not its mtime, so shows the old timestamp and backup tools that key on mtime can skip the change entirely.
  • Bash wildcards never match dotfiles, so quietly leaves and alone.
  • Numbers are absolute, letters are relative. sets all nine bits and wipes any setuid, setgid, or sticky bit on the file; only adds one bit.
  • root ignores the read and write bits, so hides nothing from a root process or from anyone with sudo.

chmod FAQ

What does chmod 755 mean?

Each digit is a sum of read (4), write (2), and execute (1) for one class of user: owner, group, others, in that order. 755 is 7 (4+2+1, rwx) for the owner and 5 (4+1, r-x) for group and others: the owner can do everything, everyone else can read and execute but not modify. It is the standard mode for directories, scripts, and binaries. 644 is the file equivalent: owner reads and writes, everyone else only reads, and nobody executes. If translating digits in your head gets old, the chmod calculator on this site converts between octal, symbolic, and checkbox form.

Why is chmod 777 bad?

777 gives every user on the system write access, so any process or account, including a compromised web app, can replace the file with anything. On a web server that turns one small exploit into a persistent backdoor. 777 is usually reached for when the real problem is ownership: the web server runs as www-data but the files belong to root or your user. The correct fix is chown -R www-data:www-data on the writable directories plus 755/644 modes, or adding your user to the right group with 775/664. The only mostly-legitimate 777-style mode is 1777 on /tmp, where the sticky bit stops users deleting each other's files.

What chmod do I use for an SSH key?

The private key must be readable by you alone: chmod 600 ~/.ssh/id_ed25519 (400 also works and is what AWS suggests for .pem files). The ~/.ssh directory itself needs 700, authorized_keys on the server needs 600, and your home directory must not be group- or world-writable. OpenSSH enforces this: a private key with loose permissions is refused with an UNPROTECTED PRIVATE KEY warning, and a server with StrictModes (the default) silently ignores authorized_keys when the path to it is too open. Nothing is logged to the client, so the server side shows up only as Permission denied (publickey).

Does chmod require sudo?

Not for your own files. Only the owner and root may change a file's mode, and no permission setting changes that: a 777 file still refuses chmod from anyone but its owner, and group membership does not help. That is also how the two failures differ. Operation not permitted means you are not the owner, so you need sudo or chown. Permission denied usually means you cannot even reach the file, because some directory on the path lacks execute for you. Anything under /etc, /usr, or /var, or owned by a service account, needs sudo. chown always needs root, which is why chmod 777 gets reached for when handing the file to the right user is the real fix.

How do I chmod all files in a directory recursively?

chmod -R applies a mode to everything under a directory, but one number is usually wrong for a tree: files want 644 and directories want 755, because execute on a directory means permission to enter it, and 644 directories become untraversable while 755 files become needlessly executable. Either run two find commands, find dir -type d -exec chmod 755 {} + and find dir -type f -exec chmod 644 {} +, or use the capital X in one pass: chmod -R u+rwX,go+rX dir, which sets execute only on directories and files that are already executable.

Related cheat sheets