Skip to content

chmod Calculator

A chmod calculator converts between the octal modes Unix commands take (644, 755, 2775) and the rwxr-xr-x symbolic notation ls -l prints. Tick the boxes or type the number — both are views of the same 12 permission bits, and this page explains in plain English who each mode lets in.

Permission bits by class
ClassRead (4)Write (2)Execute (1)Octal
Owner (user)6
Group4
Others4
Special bits (the leading 4th digit)
Symbolic notation
rw-r--r--

Mode 644 (rw-r--r--)

World-readable
  • The owner can read and write.
  • Members of the file's group can read.
  • Everyone else can read.
chmod 644 path/to/file

Common presets

How the numbers are built

A Unix file mode is twelve bits. The bottom nine split into three groups of three: owner, group, and others. Within each group the bits are read (4), write (2), and execute (1), and they simply add up. Read plus write is 6. Read plus execute is 5. All three is 7. That is the entire arithmetic — chmod 754 means owner 7 (rwx), group 5 (r-x), others 4 (r--).

The three bits above those nine are the special bits, and they are what the optional fourth digit carries: setuid (4000), setgid (2000), and the sticky bit (1000). chmod 755 and chmod 0755 are identical because the leading digit defaults to zero. When you see a four-digit mode like 2775, the leading 2 is setgid, not part of the permission arithmetic.

OctalSymbolicReadWriteExecute
0---nonono
1--xnonoyes
2-w-noyesno
4r--yesnono
5r-xyesnoyes
6rw-yesyesno
7rwxyesyesyes

Reading ls -l output

ls -l prints ten characters. The first is the file type — - for a regular file, d for a directory, l for a symlink, c/b for device nodes. The remaining nine are the owner, group, and other triads. So drwxr-x--- is a directory the owner can do anything with, the group can enter and list, and everyone else cannot touch at all: mode 750.

Read the full explanation of chmod calculator results ↓

The special bits hijack the execute position of their triad, which is why they are easy to misread. A lowercase s in the owner's execute slot means setuid and execute are both set. An uppercase S means setuid is set but execute is not — nearly always a mistake. The same rule applies to s/S in the group slot for setgid, and t/T in the others slot for the sticky bit. drwxrwxrwt on /tmp is mode 1777: world-writable, but sticky, so users cannot delete each other's files.

What execute means on a directory

This trips up nearly everyone. On a directory, the three bits do not mean what they mean on a file:

  • Read (`r`) lets you list the names inside. Without it, ls fails — but you can still open a file inside if you know its exact name and have execute.
  • Write (`w`) lets you create, delete, and rename entries. Note that deleting a file depends on the *directory* being writable, not the file. This is why you can delete a read-only file you do not own from a directory you do own.
  • Execute (`x`) — often called the *search* bit — lets you traverse into the directory and stat things inside it. Without it, nothing below the directory is reachable at all, whatever the permissions down there say.

The practical consequence: a directory almost always needs its execute bit set wherever it has read. chmod -R 644 across a tree is the classic self-inflicted outage — it strips x from every directory and the whole path becomes unreachable, producing 403s from the web server for files that are perfectly readable. Use find to set files and directories separately.

# Directories to 755, files to 644 — never a blanket chmod -R
find /var/www/html -type d -exec chmod 755 {} +
find /var/www/html -type f -exec chmod 644 {} +

# Symbolic form does the same thing in one pass:
# capital X sets execute ONLY on directories and files that already have it
chmod -R u=rwX,go=rX /var/www/html

# See what you have before you change it
stat -c '%a %A %U:%G %n' /var/www/html/index.php   # Linux
stat -f '%Lp %Sp %Su:%Sg %N' /var/www/html/index.php  # macOS/BSD
The correct recursive reset for a web root

Why 777 is almost always the wrong fix

chmod 777 grants read, write, and execute to every account on the machine. On a shared host that includes every other customer. On a VPS it includes every service account — the mail daemon, the monitoring agent, and anything an attacker manages to run as nobody. A world-writable PHP file is a persistent backdoor waiting for anyone who can already run code as any user at all; they rewrite your file, and the web server executes it as itself.

It is also almost never the actual fix. "Permission denied" from a web application means the *web server user* cannot read or write the path. The correct remedy is to make that user the owner, or put it in the owning group, and keep the mode restrictive. chown -R www-data:www-data uploads && chmod 755 uploads solves the upload-directory problem properly; chmod 777 uploads solves it by removing the lock from the door.

If you have already run chmod -R 777 on a web root, treat the site as potentially compromised: anything with write access could have modified it in the window. Restore files from source control rather than just tightening the mode.

Modes worth memorising

ModeSymbolicUse for
644rw-r--r--Static web files, PHP source, config that is not secret
755rwxr-xr-xDirectories, shell scripts, binaries
640rw-r-----Files the web server group must read but the world must not
600rw-------.env, wp-config.php, API tokens, ~/.ssh/id_ed25519
700rwx------~/.ssh, private deploy directories
444r--r--r--Files you want to make accidental-edit-proof
1777rwxrwxrwtShared scratch directories like /tmp — sticky, so only owners delete
2775rwxrwsr-xGroup-collaborative directories; new files inherit the group

SSH is the strictest consumer of permissions you are likely to meet. sshd refuses to use a private key that any group or other can read, and refuses ~/.ssh/authorized_keys if the home directory itself is group-writable — silently falling back to password auth, which then fails. 700 on ~/.ssh, 600 on private keys, 644 on authorized_keys and public keys.

umask: why new files are never 777

Processes create files requesting mode 666 and directories requesting 777; the umask then subtracts bits. The common default 022 clears write for group and other, producing 644 files and 755 directories. A umask of 002 produces 664 and 775, which is what you want on a machine where a group collaborates. umask masks bits off — it can never add a bit that the creating program did not ask for, which is why new files are never executable by default.

umask          # -> 0022
umask -S       # -> u=rwx,g=rx,o=rx

# 666 & ~022 = 644 for files; 777 & ~022 = 755 for directories
install -m 600 /dev/null secret.env   # bypass umask explicitly
Inspecting and reasoning about umask

Symbolic chmod, when it is the better tool

Octal sets every bit at once, which is exactly what you want for a known target state and exactly what you do not want for a targeted change. Symbolic mode edits bits relative to what is there: chmod +x deploy.sh adds execute for everyone the umask allows, chmod u+x,go-w file adds owner-execute and removes group/other write in one call, and chmod g=u file copies the owner triad onto the group. The capital X mentioned above only adds execute where it makes sense, which makes chmod -R u=rwX,go=rX safe on a mixed tree where a blanket octal recursion would not be.

One thing chmod cannot do is change *who* the owner and group are — that is chown and chgrp. If a mode looks right and access still fails, check ownership next, then check every parent directory's execute bit, then check whether SELinux or AppArmor is denying it (ausearch -m avc on RHEL-family systems will tell you in seconds what ls -l never will).

htpasswd Generator
Bcrypt htpasswd lines for basic auth

Frequently asked questions

What is the difference between 755 and 644?
755 adds the execute bit for everyone, 644 does not. Use 755 for directories (where execute means "may traverse") and for scripts you intend to run directly. Use 644 for ordinary files — HTML, CSS, images, and PHP source, which the interpreter reads rather than executes.
Is chmod 777 ever acceptable?
Almost never on a multi-user or internet-facing machine. The narrow legitimate case is a shared scratch directory, and even then you want 1777 so the sticky bit stops users deleting each other's files — which is precisely how /tmp is configured. If a tutorial says to chmod 777 an uploads folder, the real fix is chown to the web-server user.
Why do I get a 403 after running chmod -R 644?
You stripped the execute bit from every directory, so the web server can no longer traverse into them. Files being readable does not help if the path to them is not searchable. Fix it with find /path -type d -exec chmod 755 {} +, then set files back to 644 separately.
What does the fourth digit mean?
It carries the special bits: 4 = setuid, 2 = setgid, 1 = sticky. 2775 is setgid plus rwxrwxr-x. On a directory, setgid makes new files inherit the directory's group, which is the standard trick for a shared project folder. Setuid on a directory does nothing on Linux.
Why does my SSH key stop working after I copy it to a new machine?
Copying usually lands it at 644. sshd refuses any private key readable by group or other and will not tell you why beyond "Permissions are too open". Run chmod 600 ~/.ssh/id_ed25519 and chmod 700 ~/.ssh. A group-writable home directory will also break authorized_keys lookups.
What is the difference between a capital S and a lowercase s in ls output?
Lowercase s means the special bit and the execute bit are both set. Uppercase S means the special bit is set but execute is not — a setuid file that nobody can execute, which is almost always an accident from setting 4644 instead of 4755.
Do these permissions apply to symlinks?
Not meaningfully. A symlink's own mode is typically 777 and is ignored on Linux; access is decided by the permissions of the target. chmod follows the link by default and changes the target, which surprises people — use chmod -h on systems that support it if you really mean the link itself.
How do I see the octal mode of an existing file?
On Linux, stat -c "%a %n" file. On macOS or BSD, stat -f "%Lp %N" file. ls -l only gives you the symbolic form, which this calculator will convert back to octal if you type it in.