FormatterHQ

DevOps

Linux File Permissions and chmod Explained: 644, 755 and Beyond

How read, write and execute work for files and directories, how to choose and apply octal or symbolic chmod modes, and how umask and the special bits fit in.

FormatterHQ Team Published 7 min read

Linux file permissions decide who can read a file, change it or run it, and who can list, create or delete entries in a directory. Most permission problems on servers come down to a handful of ideas: three classes of user, three permission bits, how directories reinterpret those bits, and the default mask that shapes every new file. This guide explains each of them, shows how to read ls -l output, and covers octal and symbolic chmod modes, umask, the special bits and safe recursive changes. Use the chmod calculator alongside to convert any mode as you go.

Reading Linux file permissions in ls -l output

Run ls -l and the first column holds ten characters:

$ ls -l
-rw-r--r-- 1 deploy www-data 2048 Sep 30 09:12 index.php
drwxr-x--- 2 deploy deploy   4096 Sep 30 09:12 private
-rwxr-x--- 1 deploy deploy    512 Sep 30 09:12 deploy.sh
CharactersMeaningExample drwxr-x---
1File type: - regular file, d directory, l symbolic linkd = directory
2–4User (owner) permissionsrwx
5–7Group permissionsr-x
8–10Other (everyone else) permissions---

The owner and group follow the link count (deploy and www-data above). The kernel checks only one class per access: if you are the owner, the owner bits apply even when the group bits would allow more. To see the numeric mode directly, use stat -c '%a %A %n' index.php on Linux, which prints 644 -rw-r--r-- index.php; on macOS the equivalent is stat -f '%Lp %Sp %N' index.php.

What r, w and x mean for files and directories

The same three letters mean different things depending on the object:

BitOn a fileOn a directory
r (4)Read the contentsList the names inside it
w (2)Modify the contentsCreate, delete and rename entries (needs x too)
x (1)Run it as a programEnter it and access entries by name

The directory x bit is the one that trips people up. Without it you cannot cd into the directory or open any file inside it, even a file that is itself world-readable. A directory with r but no x lets you list names but not open or inspect them. It also follows that deleting a file depends on the directory's write and execute bits, not on the file's own permissions: a read-only file in a directory you can write to can still be removed.

Octal and symbolic chmod modes

An octal mode is three digits, one each for user, group and other, where each digit adds read (4), write (2) and execute (1). A symbolic mode names the class (u, g, o or a for all), an operator (+ adds, - removes, = sets exactly) and the permissions:

chmod 640 app.log            # set the whole mode: rw-r-----
chmod u=rw,g=r,o= app.log    # the same, symbolically
chmod g+w shared.txt         # add group write, leave the rest alone
chmod o-rwx secrets.yml      # remove every permission for others
chmod a+x build.sh           # make executable for everyone

The practical difference is that octal always replaces the entire mode, while + and - change only the bits you name. Symbolic modes are safer when you want to adjust one permission on files that currently have different modes. Typing a mode into the chmod calculator shows both forms side by side; for 750 on a deploy script it returns:

Octal:      750
Symbolic:   rwxr-x---

Owner (u):  read, write, execute
Group (g):  read, execute
Others (o): no access

Commands:
  chmod 750 deploy.sh
  chmod u=rwx,g=rx,o= deploy.sh
  chmod -R 750 directory/   # recursive

Each octal digit is exactly three bits, which is why the notation fits so well. The octal to binary converter shows 7 as 111 and 5 as 101, and the octal to decimal converter explains why 755 is 493 when a program asks for the mode as a plain integer.

When to use 644, 755, 600 and 700

ModeSymbolicUse it for
644rw-r--r--Ordinary files that others may read: static assets, .htaccess, public config
755rwxr-xr-xDirectories and programs that others need to enter or run
600rw-------Secrets: private keys, .env files, credentials
700rwx------Private directories such as ~/.ssh, personal scripts

OpenSSH checks key permissions and refuses a private key that other users can read. After creating a pair with the SSH key generator, the calculator produces the command to lock it down:

Octal:      600
Symbolic:   rw-------

Owner (u):  read, write
Group (g):  no access
Others (o): no access

Commands:
  chmod 600 ~/.ssh/id_ed25519
  chmod u=rw,g=,o= ~/.ssh/id_ed25519
  chmod -R 600 directory/   # recursive

For web servers, prefer giving the server's group read access (640 or 750) over opening files to everyone. If an .htaccess file built with the .htaccess redirect generator has no effect, check that Apache can read it and enter every parent directory. Avoid 777: a world-writable file or directory lets any local user or compromised process change it. Correct ownership with chown is almost always the real fix.

umask: where default permissions come from

New files start from 666 and new directories from 777, and the process umask removes bits from those values. The umask is a mask, not a subtraction: each bit set in the umask is cleared from the default.

umaskNew filesNew directoriesTypical setting
022644755Common default for users
002664775Shared group workflows
027640750Servers and service accounts
077600700Private, single-user data

The masking matters with odd values: umask 033 gives files 644, not 633, because the execute bits it removes were never set on a new file. Run umask to see the current value (0022) or umask -S for the symbolic form (u=rwx,g=rx,o=rx). Set it in a shell profile, a systemd unit (UMask=0027) or a container entrypoint. Bind mounts in containers keep the host's modes and numeric owners, which is worth remembering when following the docker run to Compose guide.

setuid, setgid and the sticky bit

A fourth, leading octal digit holds three special bits:

  • setuid (4): an executable runs with its owner's identity. /usr/bin/passwd uses it so users can update the password database.
  • setgid (2): on an executable it runs with the file's group; on a directory, new entries inherit the directory's group.
  • sticky (1): on a directory, only the file's owner, the directory's owner or root can delete or rename a file, as on /tmp (1777).

A shared team directory is the everyday use of setgid. The calculator output for 2775 on /srv/shared:

Octal:      2775
Symbolic:   rwxrwsr-x

Owner (u):  read, write, execute
Group (g):  read, write, execute
Others (o): read, execute
Special:    setgid

Commands:
  chmod 2775 /srv/shared
  chmod u=rwx,g=rwx,o=rx /srv/shared
  chmod -R 2775 directory/   # recursive

The symbolic command in that output sets only the nine basic bits, so use the octal form (or add g+s) when the special bit matters.

Symbolically, set the bits with chmod g+s dir, chmod +t dir or chmod u+s file. Linux ignores setuid on interpreted scripts, and file systems mounted with nosuid ignore it entirely. From a defensive point of view, setuid-root binaries deserve regular review; list them with find / -xdev -perm -4000 -type f and remove the bit from anything that does not need it. Note that GNU chmod 755 dir keeps an existing setgid bit on a directory; clearing it numerically requires chmod 00755 dir, as described in the GNU coreutils manual.

Using chmod -R without breaking things

A recursive octal mode applies the same bits to files and directories alike, which is rarely what you want: 644 removes the x that directories need, and 755 makes every data file executable. Target each type separately with find:

find /var/www/app -type d -exec chmod 750 {} +
find /var/www/app -type f -exec chmod 640 {} +
find /var/www/app -type f ! -perm 640 -print   # verify: prints nothing when done
  • Double-check the path before pressing Enter; a stray space after a leading / turns a change to one directory into a change to the whole file system.
  • Use chmod -c (GNU) to print only the files whose mode actually changed.
  • Restore executables such as artisan or scripts in bin/ afterwards with chmod u+x.

Quick reference

Read the ten-character string as type plus three triads; remember that directories need x to be usable; reach for 644 and 755 for shared content and 600 and 700 for secrets; set a sensible umask so new files start right; treat setuid and 777 as exceptions to justify. When you need a mode quickly, the chmod calculator converts between octal, symbolic and checkboxes, including the special bits, and runs entirely in your browser.

  • Linux
  • chmod
  • file permissions
  • umask
  • security

Frequently asked questions

What is the difference between chmod 755 and 644?
755 (rwxr-xr-x) lets the owner read, write and execute and everyone else read and execute. 644 (rw-r--r--) removes execute for all, so it suits ordinary files, while 755 suits directories and programs.
Why do I get Permission denied on a file that is readable?
Every directory on the path must have the execute bit for you. A file with mode 644 inside a directory with mode 700 owned by another user cannot be opened, because you cannot traverse the directory.
How do I see a file's permissions as a number?
On Linux, stat -c '%a %n' file prints the octal mode, for example 644 file. On macOS use stat -f '%Lp %N' file.
Is chmod 777 ever a good idea?
Rarely. It lets every user and process on the system modify or replace the file. Fix ownership with chown and grant access through the group instead; reserve world-writable directories for shared locations like /tmp, which also carry the sticky bit.

Tools used in this guide