⚡ AMP
Linux

Linux file permissions and chmod explained with examples

A practical guide to linux file permissions and chmod explained with examples.

Nitheesh DR 4 min read

Linux File Permissions and chmod Explained with Examples

You deploy a script, it fails with "Permission denied," and your first instinct is chmod 777 because it makes the error go away. It does — and now any user on that machine can read, write, and execute the file. On a shared server or a container with a compromised process, that's a real hole, not a shortcut. Understanding what the permission bits actually mean takes ten minutes and removes the temptation entirely.

Reading the permission string

ls -l deploy.sh
# -rwxr-xr-- 1 nitheesh staff 812 Sep 12 10:03 deploy.sh

Break -rwxr-xr-- into four groups:

So nitheesh can edit and run this script, anyone in the staff group can run it but not edit it, and everyone else can only view it.

chmod with symbolic notation

chmod u+x deploy.sh      # add execute for the owner
chmod g-w deploy.sh      # remove write for the group
chmod o=r deploy.sh      # set "others" to read-only, exactly
chmod a+r deploy.sh      # add read for everyone (a = all)

This is usually clearer than numeric mode when you're making a targeted change, since it reads like what it does.

chmod with numeric (octal) notation

Each permission is a bit: read = 4, write = 2, execute = 1. Add them per group:

chmod 755 deploy.sh
# owner: 7 = rwx (4+2+1)
# group: 5 = r-x (4+0+1)
# other: 5 = r-x (4+0+1)

chmod 644 config.json
# owner: 6 = rw- (4+2+0)
# group: 4 = r-- (4+0+0)
# other: 4 = r-- (4+0+0)

755 is the standard mode for executable scripts and directories. 644 is standard for regular files that shouldn't be executable — config files, source code, data files.

Why 777 is almost always wrong

chmod 777 deploy.sh
# rwxrwxrwx — literally everyone can read, edit, and run this file

On a single-user dev machine this is mostly harmless. On a shared server, in a Docker image, or on anything internet-facing, it means any process running as any other user — including a compromised web app on the same box — can modify the file. The "permission denied" error you were fixing is almost always solved by chmod +x (adding execute for the owner) or fixing actual ownership with chown, not by opening everything to everyone.

Ownership matters as much as the bits

chown nitheesh:staff deploy.sh   # set owner and group
sudo chown www-data:www-data /var/www/app   # common web server pattern

Permission bits are meaningless without knowing who they apply to. A file owned by root with 644 permissions can't be edited by your deploy user even though 644 "looks" reasonable — because your user falls into the "other" bucket, which only has read access.

Directories need execute to be enterable

This confuses people coming from other OSes: on a directory, the execute bit doesn't mean "run it," it means "you can cd into it and access files inside by name."

chmod 755 mydir   # can list, enter, and traverse
chmod 644 mydir   # can list contents, but NOT cd into it — usually not what you want

Common mistakes

What I'd actually use

755 for executables and directories, 644 for everything else, and fix ownership with chown before ever reaching for broader permissions. If something genuinely needs group-shared write access, use a shared group and chmod 664/775 rather than opening it to the entire system with 777.

Next steps

Run find /path/to/project -perm -o+w to find any world-writable files in your project — that's a quick audit for accidental 777s left over from past "just make it work" fixes.