chmod sets Unix file permissions using either octal notation (e.g. 755) or symbolic notation (e.g. rwxr-xr-x). The three digits represent owner, group, and others — each combining read (4), write (2), and execute (1) bits. Plus optional setuid, setgid, and sticky bits. This free chmod calculator converts between octal and symbolic in both directions, with explanations of each special bit.
Examples
What is chmod and how do Unix permissions work?
chmod ("change mode") is a POSIX command for setting file and directory permissions on Unix-like systems — Linux, macOS, BSD, WSL, even modern containers. The permission model dates to 1971's Unix V1 and has barely changed since: every file has an owner (user), a group, and rules for everyone else, with three permission bits each (read, write, execute). That's nine bits — three classes × three rights — neatly encoded in three octal digits.
This 9-bit model has survived 50+ years for a reason: it's just expressive enough to handle most real-world cases (config files, executables, web roots, log files) while being simple enough to reason about at a glance. Modern systems extended it with ACLs (access control lists), capabilities, AppArmor/SELinux, and namespaces — but plain chmod is still where 95% of permission decisions are made daily.
# ls -l output for a file
-rwxr-xr-- 1 anees devs 2048 Apr 30 12:34 deploy.sh
│└┬┘└┬┘└┬┘
│ │ │ └─── Others (everyone else): r-- = read only
│ │ └────── Group (devs): r-x = read + execute
│ └───────── Owner (anees): rwx = read + write + execute
└─────────── File type: - (regular file), d (directory), l (symlink)
The three classes — Owner, Group, Others
Every file has exactly three permission classes:
- Owner (user,
u) — the user who owns the file. Set bychown. By default, the user who created the file. - Group (
g) — the file's group. Members of this group get the group permissions. Set bychgrp. - Others (
o) — everyone on the system who isn't the owner and isn't in the group.
The shorthand a ("all") refers to all three classes simultaneously — chmod a+r file grants read to everyone.
The three permissions — Read, Write, Execute
| Bit | Symbol | Octal value | On a file | On a directory |
|---|---|---|---|---|
| Read | r | 4 | View file contents | List directory contents (ls) |
| Write | w | 2 | Modify or delete the file | Create / delete / rename entries inside |
| Execute | x | 1 | Run as a program | Enter the directory (cd); access entries by name |
Each class gets a 3-bit value combining its permissions: rwx = 4+2+1 = 7. r-x = 4+0+1 = 5. rw- = 4+2+0 = 6. The three octal digits combine all three classes: 755 = owner-rwx, group-rx, other-rx.
chmod 7XX = full owner access; chmod X75 = group can run/read; chmod XX0 = no access for "others". Memorize 4+2+1 once and you can read any chmod number forever.
Common chmod values — copy-paste cheatsheet
| Octal | Symbolic | Use case |
|---|---|---|
644 | rw-r--r-- | Standard file — owner can edit, others can read. Default for most documents, configs, web assets. |
755 | rwxr-xr-x | Standard directory or executable — owner has full control, others can read & traverse. Default for /var/www, scripts, binaries. |
600 | rw------- | Private file — only the owner can read or write. SSH private keys, auth tokens, secrets. |
700 | rwx------ | Private directory — only owner can enter and modify. ~/.ssh, home directories on multi-user systems. |
666 | rw-rw-rw- | World-writable file — anyone can edit. Almost always wrong; auditors flag this. |
777 | rwxrwxrwx | World-writable + executable — security disaster. NEVER use except for tmpfs or fully isolated containers. |
444 | r--r--r-- | Read-only for everyone — no writes even by the owner. Use for immutable configs. |
755 + setuid (4755) | rwsr-xr-x | Executable runs as the owner regardless of who launches it. Used by sudo, passwd. Rarely written by hand. |
2775 | rwxrwsr-x | Setgid directory — files created inside inherit the directory's group. Useful for shared team directories. |
1777 | rwxrwxrwt | Sticky bit — anyone can write, but only the owner can delete their own files. /tmp uses this. |
Octal vs symbolic notation — when to use each
Octal (numeric)
Three digits, fastest to type, sets all three classes at once. Best for setting fresh permissions from scratch.
chmod 755 deploy.sh # rwxr-xr-x
chmod 600 ~/.ssh/id_rsa # rw------- (SSH key)
chmod 644 *.html # rw-r--r-- (HTML files)
chmod -R 755 /var/www # recursive — entire directory tree
Symbolic (letter notation)
Letter codes for class (u/g/o/a) + operator (+/-/=) + permission (r/w/x). Best for tweaking existing permissions without touching others.
chmod +x script.sh # add execute for everyone (a+x is implied)
chmod u+x script.sh # add execute for owner only
chmod g-w shared.txt # remove write for group
chmod o=r config.yml # set others to read-only (clears w/x)
chmod a-w *.json # remove write for all classes
chmod u+rwx,g+rx,o-rwx file # combine multiple in one command
chmod -R u+w project/ # recursive: add owner-write everywhere
Rule of thumb: use octal for setting initial permissions, use symbolic for adjustments. The two are interchangeable — every chmod tool (including this calculator) shows both.
Special permission bits — setuid, setgid, sticky
Beyond the 9 standard bits, three special bits add advanced behaviors. They're encoded as a leading 4th octal digit (4000 = setuid, 2000 = setgid, 1000 = sticky), or set symbolically with u+s, g+s, +t.
| Bit | Octal | Symbolic | Effect on file | Effect on directory |
|---|---|---|---|---|
| setuid | 4xxx |
u+s (shows as s in user execute slot) |
Executable runs with owner's privileges (e.g. root) | Ignored on most Linuxes |
| setgid | 2xxx |
g+s (shows as s in group execute slot) |
Executable runs with group's privileges | New files inside inherit the directory's group (great for team folders) |
| sticky | 1xxx |
+t (shows as t in others execute slot) |
Historically: keep program in swap. Now: ignored. | Only the file owner can delete their own files (used by /tmp) |
Setuid in the wild
$ ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 232416 ... /usr/bin/sudo
↑
's' instead of 'x' = setuid set. sudo runs as root no matter who calls it.
Setuid binaries are an attack surface. A bug in a setuid program = local privilege escalation. Modern hardened systems use Linux Capabilities (per-process privilege flags) or SELinux/AppArmor instead. Don't add setuid to your own binaries unless you absolutely need it.
chmod in scripts — common patterns
Make a script executable
chmod +x deploy.sh # most common — adds x for all classes
chmod u+x deploy.sh # safer — only owner gets execute
./deploy.sh # now you can run it
Lock down SSH keys (mandatory for SSH to work)
chmod 700 ~/.ssh # directory: only owner can enter
chmod 600 ~/.ssh/id_rsa # private key: only owner reads/writes
chmod 644 ~/.ssh/id_rsa.pub # public key: anyone can read
chmod 600 ~/.ssh/authorized_keys # logins file: owner-only
chmod 600 ~/.ssh/known_hosts # known hosts: owner-only
Web server file permissions
# Standard pattern for Apache / nginx
chown -R www-data:www-data /var/www/site
find /var/www/site -type d -exec chmod 755 {} \; # directories
find /var/www/site -type f -exec chmod 644 {} \; # files
chmod 600 /var/www/site/.env # secrets file
Reset permissions on a freshly cloned repo
# Clear weird permissions inherited from Windows / archive
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
find . -name '*.sh' -exec chmod +x {} \; # restore script execute
Programmatic chmod in Python
import os, stat
# Set permissions (note: the leading 0o for octal literal)
os.chmod('deploy.sh', 0o755)
# Add execute permission without affecting others
current = os.stat('script.sh').st_mode
os.chmod('script.sh', current | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
chmod in Node.js
import { chmod } from 'node:fs/promises';
await chmod('deploy.sh', 0o755);
await chmod('id_rsa', 0o600); // private key
The umask — your default permission mask
When a process creates a new file, the OS doesn't grant arbitrary permissions — it starts from a "maximum" (666 for files, 777 for directories) and subtracts the bits in your umask. Common umask values:
| umask | New file permission | New directory permission | Use case |
|---|---|---|---|
022 | 644 | 755 | Default on most Linuxes — files readable by everyone, only owner writes. |
077 | 600 | 700 | Maximum privacy — only owner sees anything new. Default on multi-user shells like Tilde clubs. |
002 | 664 | 775 | Group-writable by default. Useful for shared development directories. |
027 | 640 | 750 | Group reads, others get nothing. Common on Debian for system files. |
# Check current umask
umask # → 0022 (the leading 0 is octal indicator)
# Set for current shell session
umask 077 # tighter — owner-only by default
# Set permanently in shell config
echo 'umask 022' >> ~/.bashrc
Best chmod calculator for 2026 — what to compare
Search results for "chmod calculator", "chmod 755 meaning", and "linux file permissions calculator" return a mix of static cheatsheets and interactive calculators. Three things separate the good from the noise: bidirectional conversion (octal ↔ symbolic both directions, not just one), special-bit support (setuid / setgid / sticky bit are missing from most), and whether the output is a copy-ready chmod command or just the permission string. Here is how the most-used chmod tools compare in 2026:
| Tool | Bidirectional | Special bits (4/2/1) | Copy-ready command | Recursive flag preview | Cost |
|---|---|---|---|---|---|
| FreeDevTool Chmod Calculator | Octal ↔ symbolic ↔ checkboxes | setuid + setgid + sticky | Yes | Yes (-R hint) | Free |
| chmod-calculator.com | Checkbox → octal | setuid + setgid only | Yes | No | Free, ad-funded |
| chmodcommand.com | Checkbox → octal | None | Yes | No | Free, ad-heavy |
| permissions-calculator.org | Checkbox → octal/symbolic | None | Partial | No | Free |
stat -c "%a" (CLI) | Read existing only | Yes | N/A (read tool) | N/A | Built-in |
| VS Code Remote-SSH file properties | Tree view only | Limited | No | No | Free |
What does chmod 755 mean and when should I use it?
chmod 755 sets these permissions: owner = rwx (read + write + execute = 4+2+1=7), group = r-x (read + execute = 4+0+1=5), others = r-x (read + execute = 5). The mnemonic is "owner can do everything, everyone else can read and run". Use 755 for: executable scripts and binaries in /usr/local/bin, web-accessible directories in Apache/nginx (so the web server can read+enter them), and shared utility scripts on a multi-user server. NOT for: regular text/data files (use 644), private SSH keys (use 600), files with sensitive info (use 600 owner-only). Common companion: chmod 644 for files inside a 755 directory — directory needs execute (to enter), files don't.
What's the difference between chmod, chown, and chgrp?
| Command | Changes | Example | Permission needed |
|---|---|---|---|
chmod | Permission bits (rwx for u/g/o + special) | chmod 755 file.sh | Owner of file or root |
chown | Owner (and optionally group) | chown alice file.txt | root only (most cases) |
chgrp | Group only | chgrp developers file.txt | Owner if member of target group, or root |
setfacl | Extended ACLs (per-user, per-group) | setfacl -m u:bob:rx file | Owner or root |
Decision rule: you want different permissions for different users beyond owner/group/others → setfacl. You want to give a different user ownership → chown. You want to change the file's group affiliation → chgrp. Everything else (changing read/write/execute on existing owner/group/others classes) → chmod.
Chmod calculator alternative to chmod-calculator.com — 4 reasons developers switched
- Bidirectional input. Type
755, pasterwxr-xr-x, or click checkboxes — all three update each other. Most calculators only accept one input direction. - Special bits surfaced as first-class. setuid (4000), setgid (2000), and sticky bit (1000) are checkboxes here, not buried in an "advanced" tab. Critical for shared upload directories (sticky on
/tmp) or wrapping a binary that needs root (setuid onpasswd). - Copy-ready chmod command with
-Rhint. Output is the fullchmod 755 file.shcommand, with a one-click toggle for recursive (-R). No mental concatenation required. - No ads, no popups. Tools indexed for "chmod calculator" almost universally inject ads or third-party tracking. This page is browser-only and persists nothing.
Pair the chmod calculator with the Cron Expression Parser for the other classic Linux DevOps cheat-sheet operation, the Git Cheatsheet for Git permission edge cases (Git tracks executable bit only), and the DevOps Tools hub for the broader Linux/CI toolkit.
chmod best practices — and what NOT to do
- Never
chmod 777in production. World-writable files are a major security hole. If a script "needs" 777 to work, the actual problem is wrong ownership (usechown) or wrong group membership. - Use
755for directories,644for files as your default. This is the standard pattern for web roots, project directories, and content trees. - Lock down secrets to
600. SSH keys,.envfiles, OAuth tokens, anything credential-like. SSH client refuses to use keys with permissions broader than600. - Use
findfor recursive permission changes.chmod -Rapplies the same mode to files AND directories, which is rarely what you want. Usefind -type d -exec chmod 755andfind -type f -exec chmod 644separately. - Audit setuid binaries. Run
find / -perm -u+s -type f 2>/dev/nullto find them. Each one is a potential privilege escalation path. Remove ones you don't need. - Set umask in your shell profile for consistent defaults. Don't rely on system defaults — they vary by distro.
- Use ACLs (
setfacl) for complex rules. If you need "user X can read but not write while group Y has full access", traditional chmod can't express it.setfaclcan. - Capabilities > setuid for new code. Linux Capabilities (
setcap cap_net_bind_service+ep myserver) grant fine-grained privileges without needing root. Modern alternative to setuid. - Don't forget the difference between file permissions and directory permissions. A file with
644inside a700directory is inaccessible to anyone but the directory's owner — directory permissions gate file access.