Run ls -la in any directory and the first column is ten characters of
noise. Once you can read them, that column tells you everything about
who is allowed to do what with a file.
Reading the permission string
ls -laA line from the output might look like this:
-rwxr-xr-x 1 user user 8432 Apr 15 compile.sh
drwxr-xr-x 4 user user 128 Apr 14 src/
lrwxrwxrwx 1 user user 12 Apr 13 link -> src/main.cThe first character is the file type:
-— regular filed— directoryl— symbolic link
The next nine characters are three groups of three, representing permissions for the owner, the group, and everyone else:
rwx r-x r-xEach group has three slots: r (read), w (write), x (execute).
A - means that permission is absent.
So -rwxr-xr-x means: regular file; owner can read, write, execute;
group can read and execute but not write; everyone else the same.
Octal notation
Each permission is a bit[1]. Each bit has a fixed numeric value:
- read = 4
- write = 2
- execute = 1
To get the octal[2] digit for one group (owner, group, or others), add the values for the permissions that are set. That is the entire system. There is nothing else to it.
r w x
4+2+1 = 7 → rwx (full access)
4+2+0 = 6 → rw- (read and write, no execute)
4+0+1 = 5 → r-x (read and execute, no write)
4+0+0 = 4 → r-- (read only)
0+0+0 = 0 → --- (no access)You do not need to memorise these. You just need to remember: read is 4, write is 2, execute is 1. Add what you want.
A three-digit octal permission applies this once per group — owner,
then group, then others. Reading 755 out loud: owner gets 7
(4+2+1 = rwx), group gets 5 (4+1 = r-x), others get 5 (4+1 = r-x).
755 → rwx r-x r-x
644 → rw- r-- r--
600 → rw- --- ---755 is the standard permission for executables and directories you
want others to be able to read and enter but not modify.
644 is standard for files you want others to read but not change.
600 is for private files — SSH keys and the like. Only the owner
can read or write them. No one else sees anything.
chmod
chmod 755 compile.sh # set permissions by octal
chmod +x compile.sh # symbolic: add execute for all
chmod go-w compile.sh # symbolic: remove write from group and others
chmod 600 ~/.ssh/id_rsa # make an SSH key privatechmod changes file permissions. You need to own the file or be root.
The symbolic form is readable but less precise. The octal form is unambiguous and what you will use most.
chown
chmod changes what can be done with a file. chown changes who owns it.
chown user file # change the owner
chown user:group file # change owner and group
chown :group file # change group only
sudo chown root:root /usr/local/bin/mytoolYou need to be root (or use sudo) to give a file to a different owner.
You can change the group of your own files freely. The common case: a
file ends up owned by root after you ran something with sudo, and you
need to reclaim it — sudo chown $USER file.
Why this matters now
Write a shell script, try to run it:
echo '#!/bin/bash' > greet.sh
echo 'echo "hello"' >> greet.sh
./greet.shbash: ./greet.sh: Permission deniedThe file exists but the execute bit is not set. Fix it:
chmod +x greet.sh
./greet.shhelloThis will happen to you constantly in the scripting and C compilation pages ahead. The execute bit is how Unix knows a file is meant to be run, not just read.