Each file and directory in the filesystem carries several bits of metadata:

  • the (numeric) user id than owns the file
  • the (numeric) group id that owns the file
  • some permission bits to specify who can do what with the file
  • some additional metadata bits

The permission and other metadata bits form the mode of the file. For a full list, see the chmod(2) and stat(2) manual pages. This article summarises the most important bits.

Permissions

There are three groups of permissions: one for the owner of the file, one for the group, and one for everyone else. Each group consists of possible permissions: read, write, and execute. There are two common ways to represent the permissions: octal and "ls long form".

For example, here is what ls(1) shows for this article draft before I started this sentence:

-rw-rw-r-- 1 liw liw 836 Nov 10 16:33 drafts/liw-permissions.mdwn

The first column is the permission bits, plus the file type. Let's open that up:

  • the leading dash (-) indicates it is a regular file; the other common file type is the letter d for directories, but there's several others, which we'll skip here
  • then there's three groups of three letters: in the example above they are rw-, rw-, and r--, for the owner, group, and others, respectively
  • r means read permission
  • w means write permission
  • x means execute permission
  • - means lack of the permission that would be at that position

In other words, the article draft is readable and writeable by the owner and group, and readable by others, and not executable by anyone.

Reading and writing regular files is pretty obvious. Executability means the kernel will (try to) execute the file as a program. This works for both actual binaries, and for scripts in various languages. For an example of executable permissions, try ls -l /bin/*.

If you have read permissions in a directory, you can list its contents. If you have write permission, you can create or remove files in the directory. Removing a file requires modifying the directory it is in: the permissions of the file itself do not matter.

Execute permission for directories is different from files. A directory can't be meaningfully executed as a program. Instead, execute permission means whether you can access files (or subdirectories) in the directory. Accessing means using the directory in the path to a file: if you have read permission to a file, but not execute permission to its directory, you can't read the file.

Octal representation

Octal representation uses base-8 numbers. This is because there's three bits in each subset of permissions. Read permission is represented by 4, write by 2, and execute by 1. Thus, the article draft's permissions can be concisely represented as 0664 (where the leading 0 indicates octal: this is a Unix convention). After a while, this becomes easy to read and write.

Umask

The octal representation is used in a few corners of the Unix world, without a cleartext form available at all. Primarily among these is the umask, which is a bitmask of permissions to remove when a file is created. Properly behaving Unix programs create new files with a mode of 0666, unless there's a reason to use another mode, e.g., for security. The mode when creating a file is anded with the complement of the umask. A common umask is 0022 (i.e., bits for group and others for writing), which means that files are created so that the group and others can read the file, but only the owner can write. The point of this complication is to give the user the flexibility to easily control permissions of new files, which becomes important when several people need direct access to the files. See the umask(2) manual page for more information. To change the umask, you have use to the shell's built-in umask command (see your shell's manual page).

Manipulation

Permissions are manipulated with the chmod(1) command, which understands the octal form, but also has a mini-language for setting or changing the bits. See the manual page for details.

Other mode bits

For extra fun and games, look up sticky, setuid and setgid bits. These change how permission bits are interpreted. The details are intricate enough that you should read the manpages (chmod(2), stat(2)) to understand them correctly.

Post Scriptum

At this point, the metadata for this article draft looks like this:

$ stat drafts/liw-permissions.mdwn 
  File: `drafts/liw-permissions.mdwn'
  Size: 4562        Blocks: 16         IO Block: 4096   regular file
Device: fe01h/65025d    Inode: 786678      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/     liw)   Gid: ( 1000/     liw)
Access: 2013-11-10 16:27:54.092026928 +0000
Modify: 2013-11-10 17:02:04.994196802 +0000
Change: 2013-11-10 17:02:04.994196802 +0000
 Birth: -

(Note the stat(1) command, which is another handy command line utility.)

in the Octal representation section, shouldn't -rw-rw-r-- be 0664 and not 0644 as written in the article?
Comment by Felix Mon Dec 2 14:48:07 2013
Thanks, Felix, you're right. I've fixed the article now.
Comment by liw.fi Mon Dec 2 20:10:10 2013