There’s a Lot in the Dot: Filesystem Permissions and Pathnames (Part 2)

Still deeper into the dot (.) with an dive into access permissions. Study up because there's going to be a quiz.

In the previous article we saw how the hidden directory entries named . (dot) and .. (dot dot) tie the filesystem together. Those names are hard links that reference the actual filesystem object through the index number. A directory always has at least two names: . and its given name. You can always reach the parent directory through the .. entry.

Now let’s dig into how pathnames and permissions work internally. (If you’re familiar with all of this, try the quiz at the end.)

Two Paths to the Same Place

Pathnames can confuse users, but they’re actually simple when you see how they work. A pathname gives the location of an object (a file, a directory, a socket, etc.) in the filesystem. There are two kinds of pathname: absolute (or full) and relative:

No matter what your current directory is, you can always find an object through its absolute pathname. But a relative pathname is often shorter.

Following a Path

When you give a pathname to a program, how does it find the object you specified? For an absolute pathname, it reads the root directory and follows the path from there. Otherwise, the program opens the current directory and follows the path from there.

Figure 1 shows how the shell’s system calls find a directory after you type cd /home/jpeek. This figure comes from part of the filesystem tree in the previous article.

Figure 1: Finding /home/jpeek
Figure 1: Finding /home/jpeek

  1. The pathname starts with /, so the system opens the root directory.
  2. Inside the root directory, it looks for a directory entry named home. If there’s no home entry, the pathname is invalid. Otherwise, the system opens the home directory.
  3. Inside the /home directory, it looks for a directory entry named jpeek.

Here are some more examples: multiple ways to reach the same directory. I’ll start by changing the current directory to my home directory. (A simple cd with no pathname defaults to a user’s home directory.)

1$ cd
2$ ls -ai
5423 .   58 ..   5425 bin   5424 foo
3$ ls -ai .
5423 .   58 ..   5425 bin   5424 foo
4$ ls -ai ././.
5423 .   58 ..   5425 bin   5424 foo
5$ ls -ai ../jpeek
5423 .   58 ..   5425 bin   5424 foo
6$ ls -ai /home/jpeek
5423 .   58 ..   5425 bin   5424 foo
7$ ls -ai /home/jpeek/.
5423 .   58 ..   5425 bin   5424 foo
8$ ls -ai /home/jpeek/../jpeek
5423 .   58 ..   5425 bin   5424 foo
9$ ls -ai /jpeek
ls: cannot access /jpeek: No such file or directory

Every ls command lists the same directory, some through relative pathnames and some through absolute. Command 4 opens ., then opens ., then opens . again: always the same directory. Command 8 opens /home/jpeek, then the parent directory, then the jpeek directory from there — with the same result.

Why did command 9 fail? Trace it through: open the root directory, then look for an entry named jpeek. There isn’t one.

Access Permissions

Once you see how pathnames work, understanding access permissions is simple. You’re probably familar with access permissions for files: read permission lets a program read the file’s contents, write permission allows modification, and execute permission is for executable programs. Notice that none of those permissions control whether you can rename or delete the file. Why? We’ll see soon.

A directory is actually just a special type of file, and a directory’s permissions are easy to understand when you realize that a directory holds entries for other files. So:

Pathnames and the shell PATH

Pathnames work almost anywhere, with any command. One notable exception is specifying the program you want to use. If the program’s pathname contains a /, it will be followed. Otherwise, different rules apply.

For example, let’s say your current directory is /home/jpeek/bin. If you want to run the program prog from the current directory, here are three pathnames — three ways you can specify its location:

$ ls -l prog
-rwxr-xr-x 1 jpeek  238 2009-08-19 06:28 prog
$ /home/jpeek/bin/prog
$ ./prog
$ prog
bash: prog: command not found
$ echo $PATH
/usr/local/bin:/usr/bin:/bin

From ls -l, we can see that prog is a valid pathname: it’s an entry in the current directory. So why did bash say “command not found”? If you specify a program name only, without a slash, the shell will search through each directory in the PATH environment variable, looking for the program in that directory. As you can see from the last command, the current directory isn’t in $PATH. This is for security. In this case, to run a program from the current directory, you have to tell the shell ./prog. But, with other commands, the ./ is redundant; prog is simpler.

Quiz

Here’s a directory listing from ls -l, run by the superuser (who can access everything on the filesystem):

# ls -la /home/zoe
drwxrwx--x 2 zoe  users  8192 2010-03-14 18:33 .
drwx--x--x 9 root users 16384 2010-03-11 08:00 ..
-rw-r--r-- 1 zoe  users  2942 2010-03-16 13:45 afile
drwx------ 2 zoe  users  4096 2010-03-14 18:33 dir
-rw-r--r-- 1 zoe  users  4039 2009-11-22 08:18 .profile

If anything in that quiz surprised you, this might be a good time to open a terminal window and make up some exercises for yourself. Enjoy!

Jerry Peek is a freelance writer and instructor who has used Unix and Linux for more than 25 years. He's happy to hear from readers; see https://www.jpeek.com/contact.html.

[Read previous article] [Read next article]
[Read Jerry’s other Linux Magazine articles]