Where to start First steps track · 15 stages
Linux Labs

chmod / chown — permissions and ownership

6 min Linux

Changing permissions (chmod) and owner/group (chown) — numeric and symbolic syntax, umask, chgrp.

Cheat sheet

8 commands Printable version
  • chmod 644 file rw-r--r--
  • chmod 755 script rwxr-xr-x
  • chmod 600 secret owner only
  • chmod 2770 team-dir setgid: new files inherit the directory's group
  • chown user:group file owner and group
  • chown -R www-data:www-data /var/www/site recursive (typical for a web root)
  • chgrp devs file change only the group
  • umask current mask for new files

Overview

  • chmod changes permissions (rwx).
  • chown changes owner and group; chgrp changes only the group.
  • umask does not touch existing files — it sets what permissions new files and directories get by default.

The basics of the permission model are in the "Permissions" article (see "See also").

Options

10

Below are the main flags of chmod and chown; the full list is in man chmod/man chown.

Option What it does Example
-R --recursive Apply recursively through the whole directory tree. dangerous chmod -R 755 dir
-R --recursive Apply recursively through the whole directory tree. dangerous chown -R www-data:www-data /var/www/site
-v --verbose Print what was done for every file. chmod -v 644 file
-c --changes Like -v, but only for files that actually changed. chmod -c 644 file
--reference RFILE Copy the mode from another file instead of a mode argument. chmod --reference=good.txt bad.txt
-v --verbose Print what was done for every file. chown -v alice file
--reference RFILE Copy owner and group from another file instead of an argument. chown --reference=good.txt bad.txt
-f --silent Suppress most error messages. chmod -f 644 *.txt
--from CURRENT_OWNER:CURRENT_GROUP Change ownership only if the current owner/group matches. chown --from=root:root alice file
-h --no-dereference Change the ownership of the symlink itself, not its target. chown -h alice link

Nothing found. Try a shorter query.

Recipes

4

chmod

Two syntaxes:

bash
# numeric (r=4 w=2 x=1)
chmod 644 file                    # rw-r--r--
chmod 755 script                  # rwxr-xr-x
chmod 600 ~/.ssh/id_ed25519       # private key — owner only

# symbolic
chmod u+x script.sh               # +x for the owner
chmod go-w file                   # remove write for group and others
chmod a+r file                    # read for everyone
chmod -R u+rwX dir                # recursive; X = x only for dirs/already-executable files

Capital X is handy recursively: it sets x on directories but not on every file.

chown

bash
chown alice file                  # change the owner
chown alice:devs file             # owner and group
chown :devs file                  # group only
chown -R www-data:www-data /var/www/site   # recursive (typical for a web root)
chown --reference=good.txt bad.txt # copy the owner from another file

chgrp

chgrp is the same as chown :group, but shorter and more explicit about intent:

bash
chgrp devs file                   # change a file's group
chgrp -R devs dir                 # recursive
chgrp --reference=good.txt bad.txt # copy the group from another file

umask

umask is a mask whose bits the kernel clears from the default permissions when creating a file (usually 666) or a directory (777). The full story, including where the mask comes from, is in umask. It does not touch existing files — only what gets created after it is set.

bash
umask                             # show the current mask (usually 0022)
umask 022                         # files 644, directories 755 — typical for a user
umask 002                         # files 664, directories 775 — for a shared group
echo "umask 027" >> ~/.bashrc     # make it permanent (for interactive sessions)

022 removes write for group and others; 002 removes it only for others (handy when several people share a group). For system services, set the mask in the unit (UMask= in systemd), not in ~/.bashrc, which they never read.

Troubleshooting

4

chmod 777 "just in case"

Almost always wrong and dangerous (especially on directories/web roots). 777 opens write access to everyone, including unrelated users on the system. Pick the minimum you need: files 644, scripts 755, secrets 600.

A shared directory for a team is not 1777

1777 (sticky bit, world-writable) is the mode for public directories like /tmp: anyone can write, but only the owner of a file can delete it (the sticky bit). It is not protection for a team directory: any other user on the system can still create files in it. For a directory owned by one group, use 2770 plus group ownership:

bash
chown :devs team-dir
chmod 2770 team-dir               # rwxrws--- : devs only, setgid

Setgid (2) makes new files in the directory inherit its group instead of the primary group of whoever created them — the team does not lose access to what colleagues create. To stop colleagues deleting each other's files, add sticky: chmod 3770. More in Special permission bits.

Recursion broke executability

chmod -R 644 dir strips x from directories → you can no longer enter them. Use u+rwX, or split it: find dir -type d -exec chmod 755 {} + and -type f -exec chmod 644 {} +.

Changed the owner — the service stopped reading the files

Many daemons run as their own user (www-data, postgres). File ownership must match the service's user.

Danger zone

2

chmod -R / chown -R on system directories

Recursively changing /, /etc, or /usr (say, trying to "fix permissions" with one command) changes the permissions of thousands of files at once, including ones whose permissions are critical to booting: sshd refuses to read a host key with the wrong permissions, sudo stops working if its own binary has the wrong permissions. Recovery means reinstalling packages (dpkg --verify, apt install --reinstall) or restoring from a backup — there is no quick way back. Scope the command explicitly (chmod -R … /var/www/site, not chmod -R … /).

chmod 600 ~/.ssh/id_ed25519, but not the other way around

SSH refuses to use a private key that is readable by the group or others. But chmod -R 600 on all of ~/.ssh strips x from the .ssh directory itself (if applied to it too) — then you cannot enter it at all. Directory and file permissions differ: 700 for the directory, 600 for the key files.

See also

  • permissions — The Unix permission model — read/write/execute, owner/group/other, special bits.
  • umask — which permissions new files get and where the mask comes from.
  • special-bits — setuid, setgid and sticky: a team's shared directory.
  • users-groups — Accounts, groups, membership; useradd/usermod, /etc/passwd and /etc/group.
Loading…