Owner
Group
Others
chmod 644 file.txt
Convert Unix file permissions between the octal form
and rwxr-xr-x, in either direction. Click the boxes or
type the number; the chmod command updates as you go.
chmod 644 file.txt Read is 4, write is 2 and execute is 1. So 7 is all three, 6 is read and write, 5 is read and execute, and 4 is read only. The three digits cover the owner, the group and everyone else, in that order. For example, 750 gives the owner everything, the group read and execute, and everyone else nothing.
Owner can edit, everyone else can read. The normal setting for web content, config and source files.
The execute bit on a directory means traverse, not run. Without it no user can enter the directory, however readable its contents are.
Private keys, .env files, anything with a credential. SSH refuses to use a private key that other users can read, and prints an UNPROTECTED PRIVATE KEY FILE warning instead.
It lets any user on the machine rewrite the file, and on shared hosting that includes strangers. It is the standard bad fix for a permission error. Fix the owner with chown instead, because the wrong owner is nearly always the real cause.
Execute means two different things. On a file it means run it. On a directory it means you may traverse into it. Read without execute on a directory lets you list the names and touch nothing inside.
Use setgid on shared directories. New files inside inherit the directory's group rather than the creator's, which is how a shared folder stays shared without anyone remembering to run chgrp.
The sticky bit is why /tmp works. In a world-writable directory it stops users from deleting each other's files. You see it as the t in drwxrwxrwt.
Permissions are not the whole story. Ownership, umask, ACLs and SELinux all sit on top. If 644 looks right and access still fails, check who owns the file before you start loosening bits.
chmod 644 config.php # owner writes, everyone reads
chmod 755 deploy.sh # plus execute for everyone
chmod 600 ~/.ssh/id_ed25519 # SSH refuses a key anyone else can read
# Symbolic form, which is relative rather than absolute
chmod u+x script.sh # add execute for the owner only
chmod go-w shared/ # take write away from group and others
chmod a+r public/ # everyone can read
# The right way to fix a whole tree: directories and files differ
find . -type d -exec chmod 755 {} +
find . -type f -exec chmod 644 {} +
# setgid on a directory: new files inherit its group
chmod 2775 /srv/shared
# What is it now?
stat -c "%a %n" file.txt # Linux
stat -f "%OLp %N" file.txt # macOS chmod -R 755 on a source tree makes every file executable, which is wrong and hard to undo cleanly. Use find to set files and directories separately.
umask # usually 022
# New files: 666 - 022 = 644
# New directories: 777 - 022 = 755
# Files never get the execute bit by default, which is why
# a freshly created script needs chmod +x.
umask 077 # private by default: 600 files, 700 directories
# Good for a shell that handles secrets. import os
import stat
os.chmod("config.json", 0o600) # the 0o prefix is octal
# Readable check
mode = os.stat("config.json").st_mode
print(oct(stat.S_IMODE(mode))) # '0o600'
print(stat.filemode(mode)) # '-rw-------'
# Create a file that was never briefly world-readable:
# the race matters when you are writing a secret
fd = os.open("secret.txt", os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600) The sticky bit has an odd history. It originally told Unix to keep a program's text segment in swap after it exited, so it would start faster next time. That meaning is long gone; on a directory it now means only the owner of a file may delete it, which is what makes a world-writable /tmp safe to have.
This tool follows the specifications below. Read them when you need the exact normative wording, for example to settle an edge case between two implementations.
Owner can read, write and execute; group and everyone else can read and execute. Each digit is three bits: read is 4, write is 2, execute is 1, added together. It is the normal setting for a directory or a script.
644 for files and 755 for directories is the usual answer for web content. Directories need the execute bit to be entered at all, which is why 644 on a directory makes it unusable even though it looks more secure.
Almost never. It lets any user on the system rewrite the file, and on shared hosting that includes other customers. It is the classic bad advice for a permission error; the real fix is almost always correcting the owner with chown.
Special bits: setuid (4), setgid (2) and the sticky bit (1). setgid on a directory makes new files inherit its group, which keeps shared folders shared. The sticky bit on /tmp is why you cannot delete other people's files there.
On a file it means run it. On a directory it means traverse it, so you can access things inside even without permission to list the contents. Read without execute on a directory lets you see the names and nothing else.
The octal here is ordinary base-8 arithmetic, which the number base converter handles in general. For the other things that go wrong on a server, see the HTTP status reference.