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
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
dfor directories, but there's several others, which we'll skip here
- then there's three groups of three letters: in the example above
r--, for the owner, group, and others, respectively
rmeans read permission
wmeans write permission
xmeans 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 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.
The octal representation is used in a few corners of the Unix world,
without a cleartext form available at all. Primarily among these is
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
umask command (see your shell's manual page).
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.
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.)