# chmod — Manage File Permissions

> Practical guide to chmod: set file permissions in octal and symbolic notation, work recursively, and avoid 777 as a security risk.

Source: https://www.jpkc.com/db/en/cheatsheets/files-text/chmod/

<!-- PROSE:intro -->
`chmod` (change mode) controls who may read, write and execute a file or directory – separately for the owner (`u`), the group (`g`) and everyone else (`o`). Day to day you reach for it to make a script executable (`chmod +x`), lock down a private SSH key with `600`, or set web files to `644`/`755`. You can express permissions in octal (`chmod 755`) or symbolically (`chmod u+x`): octal sets every bit absolutely, while symbolic changes individual bits precisely. For security awareness, two things matter: `chmod 777` opens a file to everyone for writing and execution – it is almost never necessary and a genuine risk – and `chmod -R` deserves care, because it spreads permissions recursively across whole trees.
<!-- PROSE:intro:end -->

## Octal Mode (Numeric)

`chmod 755 <file>` — Owner: rwx, Group: r-x, Others: r-x. Standard for executable files and directories.

```bash
chmod 755 script.sh
```

`chmod 644 <file>` — Owner: rw-, Group: r--, Others: r--. Standard for regular files.

```bash
chmod 644 index.html
```

`chmod 600 <file>` — Owner: rw-, Group: ---, Others: ---. Private files, only owner can read/write.

```bash
chmod 600 ~/.ssh/id_ed25519
```

`chmod 700 <directory>` — Owner: rwx, Group: ---, Others: ---. Private directory, only owner can access.

```bash
chmod 700 ~/.ssh
```

`chmod 664 <file>` — Owner: rw-, Group: rw-, Others: r--. Shared files where group can also write.

```bash
chmod 664 shared-doc.txt
```

`chmod 775 <directory>` — Owner: rwx, Group: rwx, Others: r-x. Shared directory where group can write.

```bash
chmod 775 /var/www/shared/
```

`chmod 400 <file>` — Owner: r--, Group: ---, Others: ---. Read-only for owner, no access for anyone else.

```bash
chmod 400 secret.key
```

`chmod 444 <file>` — Owner: r--, Group: r--, Others: r--. Read-only for everyone.

```bash
chmod 444 LICENSE
```

`chmod 000 <file>` — No permissions for anyone. Only root can still access the file.

```bash
chmod 000 locked-file.txt
```

## Octal Reference

`0 = --- (no permission)` — No read, write, or execute permission.

```bash
chmod 700 dir/  # Others get 0 = ---
```

`1 = --x (execute only)` — Execute permission only. For directories: can traverse but not list.

```bash
chmod 711 cgi-bin/  # Others get 1 = --x
```

`2 = -w- (write only)` — Write permission only. Rarely used alone.

```bash
chmod 722 dropbox/  # Others get 2 = -w-
```

`4 = r-- (read only)` — Read permission only.

```bash
chmod 744 script.sh  # Others get 4 = r--
```

`5 = r-x (read + execute)` — Read and execute. Standard for others on executables and directories.

```bash
chmod 755 app.bin  # Others get 5 = r-x
```

`6 = rw- (read + write)` — Read and write. Standard for owner on regular files.

```bash
chmod 644 data.txt  # Owner gets 6 = rw-
```

`7 = rwx (read + write + execute)` — Full permissions. Standard for owner on executables and directories.

```bash
chmod 755 deploy.sh  # Owner gets 7 = rwx
```

## Symbolic Mode

`chmod u+x <file>` — Add execute permission for the owner (u = user/owner).

```bash
chmod u+x script.sh
```

`chmod g+w <file>` — Add write permission for the group (g = group).

```bash
chmod g+w shared.txt
```

`chmod o-rwx <file>` — Remove all permissions for others (o = others).

```bash
chmod o-rwx private.conf
```

`chmod a+r <file>` — Add read permission for all (a = all: owner + group + others).

```bash
chmod a+r README.md
```

`chmod u+rwx,g+rx,o+rx <file>` — Set multiple permissions at once using comma-separated expressions.

```bash
chmod u+rwx,g+rx,o+rx deploy.sh
```

`chmod u=rwx,g=rx,o=rx <file>` — Set exact permissions with = (replaces existing). Equivalent to 755.

```bash
chmod u=rwx,g=rx,o=rx script.sh
```

`chmod u=rw,go=r <file>` — Set owner to rw, group and others to read-only. Equivalent to 644.

```bash
chmod u=rw,go=r config.yml
```

`chmod +x <file>` — Add execute permission for all (shorthand, omitting 'a').

```bash
chmod +x install.sh
```

`chmod -w <file>` — Remove write permission for all. Makes the file read-only.

```bash
chmod -w important.conf
```

`chmod u+s <file>` — Set the setuid bit. File runs as the owner regardless of who executes it.

```bash
chmod u+s /usr/local/bin/my-tool
```

`chmod g+s <directory>` — Set the setgid bit. New files in the directory inherit the directory's group.

```bash
chmod g+s /var/www/shared/
```

`chmod +t <directory>` — Set the sticky bit. Only file owners can delete their files in this directory.

```bash
chmod +t /tmp/
```

## Recursive & Directory Operations

`chmod -R 755 <directory>` — Recursively set permissions on a directory and all its contents.

```bash
chmod -R 755 /var/www/html/
```

`chmod -R u+rwX,go+rX,go-w <directory>` — Recursively set permissions. Capital X adds execute only to directories and already-executable files.

```bash
chmod -R u+rwX,go+rX,go-w /var/www/html/
```

`find <directory> -type f -exec chmod 644 {} +` — Set permissions on all files only (not directories) within a tree.

```bash
find /var/www/html/ -type f -exec chmod 644 {} +
```

`find <directory> -type d -exec chmod 755 {} +` — Set permissions on all directories only (not files) within a tree.

```bash
find /var/www/html/ -type d -exec chmod 755 {} +
```

`find <directory> -type f -name '*.sh' -exec chmod +x {} +` — Make all shell scripts executable within a directory tree.

```bash
find ./scripts/ -type f -name '*.sh' -exec chmod +x {} +
```

## Special Bits (Octal)

`chmod 4755 <file>` — Set setuid (4) + owner rwx, group r-x, others r-x. File executes as owner.

```bash
chmod 4755 /usr/local/bin/my-tool
```

`chmod 2755 <directory>` — Set setgid (2) + standard directory permissions. New files inherit group.

```bash
chmod 2755 /var/www/shared/
```

`chmod 1777 <directory>` — Set sticky bit (1) + full permissions for all. Users can only delete own files.

```bash
chmod 1777 /tmp/
```

`chmod 6755 <file>` — Set both setuid (4) and setgid (2) bits. 4+2=6.

```bash
chmod 6755 /usr/local/bin/special-tool
```

## Viewing Permissions

`ls -l <file>` — Show file permissions in symbolic format (e.g. -rwxr-xr-x).

```bash
ls -l script.sh
```

`ls -la <directory>` — Show permissions for all files including hidden ones.

```bash
ls -la ~/.ssh/
```

`stat <file>` — Show detailed file status including permissions in both octal and symbolic format.

```bash
stat script.sh
```

`stat -c '%a %n' <file>` — Show only the octal permissions and filename (Linux).

```bash
stat -c '%a %n' *.sh
```

`stat -c '%A %a %n' <file>` — Show symbolic permissions, octal permissions, and filename.

```bash
stat -c '%A %a %n' /var/www/html/*
```

`namei -l <path>` — Show permissions for each component along a file path. Useful for debugging access issues.

```bash
namei -l /var/www/html/index.php
```

## Common Permission Patterns

`chmod 644 <file>` — Standard web files (HTML, CSS, JS, images). Owner can edit, everyone can read.

```bash
chmod 644 style.css
```

`chmod 755 <directory>` — Standard web directories. Owner full access, others can list and traverse.

```bash
chmod 755 /var/www/html/
```

`chmod 600 <file>` — SSH private keys, credentials, .env files. Only owner can read/write.

```bash
chmod 600 .env
```

`chmod 700 <directory>` — SSH directory, private config directories. Only owner can access.

```bash
chmod 700 ~/.gnupg
```

`chmod 644 ~/.ssh/authorized_keys` — SSH authorized_keys must be readable by owner and readable by sshd.

```bash
chmod 644 ~/.ssh/authorized_keys
```

`chmod 600 ~/.ssh/config` — SSH config file. Must be private to work correctly.

```bash
chmod 600 ~/.ssh/config
```

`chmod 755 <script>` — Executable scripts and binaries. Owner full access, others can read and execute.

```bash
chmod 755 deploy.sh
```

`chmod 640 <file>` — Log files and config files. Owner can read/write, group can read, others no access.

```bash
chmod 640 /etc/app/database.conf
```

## Options & Flags

`chmod -v <mode> <file>` — Verbose mode. Print a message for each file processed.

```bash
chmod -v 644 *.html
```

`chmod -c <mode> <file>` — Like verbose, but only report when a change is actually made.

```bash
chmod -c 755 scripts/*.sh
```

`chmod --reference=<ref_file> <file>` — Set permissions to match those of a reference file.

```bash
chmod --reference=template.conf new.conf
```

`chmod -R --preserve-root <mode> <directory>` — Prevent accidental recursive changes to the root filesystem.

```bash
chmod -R --preserve-root 755 /var/www/
```

## Ownership & umask

`chown <user>:<group> <file>` — Change the owner and group of a file.

```bash
chown www-data:www-data index.php
```

`chown -R <user>:<group> <directory>` — Recursively change owner and group for a directory tree.

```bash
chown -R www-data:www-data /var/www/html/
```

`chgrp <group> <file>` — Change only the group of a file.

```bash
chgrp developers project.conf
```

`umask` — Show the current file creation mask. Determines default permissions for new files.

```bash
umask
```

`umask 022` — Set umask so new files get 644 and new directories get 755.

```bash
umask 022
```

`umask 077` — Set restrictive umask. New files get 600, new directories get 700.

```bash
umask 077
```

<!-- PROSE:outro -->
## Conclusion

`chmod` is the central tool for controlling access precisely – day to day, a handful of patterns cover most cases: `644` for files, `755` for directories and executable scripts, `600`/`700` for private SSH and credential data. Reach for symbolic notation (`u+x`, `go-w`) when you only want to flip individual bits, and octal when you set the state completely. From a security standpoint, two rules of thumb: almost never grant `777` – it lets anyone write and execute – and be careful with `chmod -R`, since it spreads permissions across entire trees; use a capital `X` or separate `find` runs to treat files and directories differently. Permissions only govern access – who owns a file is set with `chown`.

## Further Reading

- [GNU Coreutils: chmod](https://www.gnu.org/software/coreutils/manual/html_node/chmod-invocation.html) – the official reference for every option
- [chmod(1) manual page](https://man7.org/linux/man-pages/man1/chmod.1.html) – the Linux man page covering symbolic and octal modes
- [Wikipedia: File-system permissions](https://en.wikipedia.org/wiki/File-system_permissions) – background on the Unix permission model with examples
<!-- PROSE:outro:end -->

## Related Commands

- [chown](https://www.jpkc.com/db/en/cheatsheets/files-text/chown/) – change the owner and group of a file
- [ls](https://www.jpkc.com/db/en/cheatsheets/files-text/ls/) – show permissions with ls -l
- [stat](https://www.jpkc.com/db/en/cheatsheets/files-text/stat/) – show permissions in detail in octal and symbolic form

