Updated: 2012-12-24 04:23 EST

1 Pathnames and slashes Index up to index

A Unix pathname is a text string that names something in the file system. It might name a file, a directory (“folder”), or some other thing (e.g. a disk partition or a terminal device).

A Unix pathname consists of one or more name components separated by forward slashes (not DOS backslashes!). Here are five examples of pathnames for the “file.txt” file (one example pathname per line):

/home/idallen/bin/file.txt
bin/file.txt
../bin/file.txt
./file.txt
file.txt

A pathname with only one name component doesn’t need to have any slashes to separate it from other name components. Slashes are used to separate name components.

2 Name components can contain any character except slash Index up to index

The name components between the slashes in a pathname can contain any characters except slashes - even spaces, newlines, and unprintable control characters. (Yes, you can have a file name that is entirely made of blanks or backspace characters.) Slashes separate the name components; they are never part of a name component.

Each name component in a pathname (between the slashes) is typically limited to 255 characters, with an overall Linux limit of 4,096 characters for the entire pathname. (Some Unix systems have a smaller limit.)

3 Slashes separate name components Index up to index

Consider the pathname:

/home/idallen/bin/file.txt

Since slashes always separate name components, a pathname with four slashes in it must contain five separated name components. In this example, those five name components are:

  1. “” (the nameless ROOT directory, to the left of the leftmost slash)
  2. home
  3. idallen
  4. bin
  5. file.txt

4 The ROOT directory “/” has no name Index up to index

Since slashes always separate name components, if a pathname starts with a slash, the nameless “ROOT” directory is assumed to begin the pathname. The ROOT directory has no name. It is the root of the entire Unix file system tree.

A pathname starting with a slash is called an absolute pathname, since it always starts at the ROOT.

Because it is difficult to talk about a directory that has no name, we usually (incorrectly) use the name “/” (slash) for the ROOT directory. This is wrong, because name components of a pathname can’t contain slashes and slashes separate name components. Understand that when we use “/” for ROOT, we really mean “the nameless ROOT directory that is to the left of the slash”, not the slash itself.

5 Only directories contain other pathnames Index up to index

To be a valid pathname, every name component that is to the left of the rightmost slash in a pathname must either be a directory (folder) or be a symbolic link to a directory. Only directories can have substructure that may contain other pathnames.

If the pathname /home/idallen/bin/file.txt is to be valid, the first four name components must name existing directories. (Only directories can contain other pathnames.) The four name components to the left of the rightmost slash must be names for existing directories (or be symbolic links to directories).

The final component name “file.txt” (the name to the right of the rightmost slash) is the name of the file system object itself. It might be a directory or anything else, though the name “file.txt” suggests that it is a text file name.

A name component that names a “file” cannot be followed by a slash. Only a directory name can have a slash to its right. Putting a slash to the right of a non-directory (e.g. a file) results in an invalid pathame:

$ wc /etc/passwd
  37      89    1802 /etc/passwd
$ wc /etc/passwd/
wc: /etc/passwd/: Not a directory

Putting one or more slashes at the right end of a directory pathname makes almost no difference:

$ ls /bin
...153 names print here...
$ ls /bin/
...153 names print here...
$ ls /bin//
...153 names print here...
$ ls /bin///
...153 names print here...

The final named component in the pathname, after the rightmost slash, can name anything - a file, directory, symbolic link, or other special file. If the final component is empty, the self-referential name “.” is assumed, i.e.

$ ls /bin/
...153 names print here...
$ ls /bin/.
...153 names print here...

6 Absolute and Relative pathnames Index up to index

A pathname that starts with a leading slash (indicating that the path starts at the nameless ROOT directory) is called an absolute pathname. Your current working directory has no effect on an absolute pathname, because an absolute pathname always starts at the ROOT and doesn’t depend on your current directory.

All other pathnames (with no leading slash) are called relative pathnames. These relative pathnames are evaluated relative to the current working directory. Relative pathnames (no leading slash) always start in the current directory, not in the ROOT directory.

Because relative pathnames start in the current working directory, relative pathnames act as if the current working directory were inserted in front of the pathname.

For example, if your current working directory is /usr/bin then:

If you change your current working directory to /home then:

All relative pathnames are affected by changing the current working directory. Shells have commands that let you change your current working directory so that you can type shorter pathnames.

7 Pathnames such as ~, ~user, and $HOME may become Absolute Index up to index

Most Unix shells have short-cuts that let you specify short versions of absolute pathnames but where the syntax of the short-cut doesn’t start with a slash and so the short-cut doesn’t appear to be an absolute path.

7.1 Leading tilde may mean absolute Index up to index

Shells may expand a leading tilde (~) on a token (command argument) to be the absolute pathname to some home directory, e.g. these may be equivalent:

$ cp /tmp/foo ~/bar
$ cp /tmp/foo /home/user/bar

If the tilde stands alone or is immediately followed by a slash, the home directory substituted is the home directory found in the shell variable $HOME, which is usually set to the home directory of the user who is logged in (but can be changed). For example, ls ~/bin may be expanded by the shell to be ls /home/idallen/bin.

Try this command line to see how the shell expands the tilde pathnames:

$ echo  ~  ~/bin  ~/..
/home/idallen /home/idallen/bin /home/idallen/..

If the tilde is followed by a valid account name, e.g. ~idallen, the shell replaces the tilde expression with the absolute pathname of the home directory of that account, e.g. idallen may have home /home/idallen.

Try this command line to see how the shell expands the tilde pathnames:

$ echo  ~mail  ~uucp  ~games  ~root  ~nosuch
/var/mail /var/spool/uucp /usr/games /root ~nosuch

Thus, ls ~idallen/bin secretly uses an absolute pathname, because, ~idallen is actually expanded (by the shell) to be the absolute path /home/idallen. Be aware of this!

7.2 $HOME variable may mean absolute Index up to index

Absolute pathnames may also hide inside shell variables, e.g. $HOME/foo could be expanded by the shell to be /home/idallen/foo, an absolute pathname:

$ echo  $HOME  $HOME/bin  $HOME/..
/home/idallen /home/idallen/bin /home/idallen/..

Thus, ls $HOME/bin secretly uses an absolute pathname, because, $HOME is actually expanded (by the shell) to be the absolute path /home/idallen. Be aware of this!

7.3 Rule for absolute pathnames Index up to index

A pathname is absolute if and only if it starts with a leading slash after all shell expansions are finished. If it starts with a slash, the nameless ROOT directory is always the first directory in the pathname. Otherwise, without a starting slash, the pathname is relative to the current working directory and the current working directory is prefixed to the pathname.

Watch for hidden leading slashes inserted by your shell when expanding short-cuts such as ~, ~userid, and $HOME.

8 Dot and Dot Dot – . and .. Index up to index

Every Unix directory contains the name “.” (dot), which is a name that leads right back to the directory in which it is found. Every directory contains the name “..” (dot dot), which is a name that leads to the unique parent directory of the directory in which it is found.

The ROOT directory is the only directory that is its own parent: both “.” and “..” are the same in the ROOT directory. If you go to the parent of the ROOT directory, you are still in the ROOT directory.

For example, the directory pathname /tmp contains two directories: ROOT and “tmp”. The pathname /tmp/. contains three directories, ROOT, “tmp”, and “.”. The “.” is searched for in the “tmp” directory in which it is contained, and leads right back to “tmp”; so, /tmp and /tmp/. are equivalent.

The directory pathname /./tmp contains three directories: ROOT, “.”, and “tmp”. The “.” is searched for in the ROOT directory in which it is contained, and leads right back to ROOT; so, /./tmp and /tmp are equivalent.

The directory pathname /./tmp/. contains four directories: ROOT, “.”, “tmp”, and “.”. The first (leftmost) “.” is searched for in the ROOT directory; the last (rightmost) “.” is searched for in the “tmp” directory. Thus, /./tmp/. is equivalent to just: /tmp

The directory pathname /tmp/.. contains three directories: ROOT, “tmp”, and “..”. The “..” is searched for in the “tmp” directory in which it is contained, and leads to the parent of the “tmp” directory (which is always ROOT, unless tmp is a symbolic link); so, /tmp/.. and / (ROOT) are usually equivalent.

(We won’t deal with symbolic links in this document. If /tmp is a symbolic link to a directory, not an actual directory, then /tmp/.. may not be the same as /.)

The directory pathname /home/idallen/bin/../.. contains six directories: ROOT, “home”, “idallen”, “bin”, “..”, and “..”. The first “..” is searched for in the “bin” directory in which it is contained and leads to the parent of the “bin” directory, which is “idallen”. The second “..” is therefore searched for in the “idallen” directory in which it is contained, and leads to the parent of the “idallen” directory, which is “home”. Thus, /home/idallen/bin/../.. is usually equivalent to /home.

Each “..” in a pathname backs up one directory level.

The directory pathname /../tmp contains three directories: ROOT, “..”, and “tmp”. The “..” is searched for in the ROOT directory in which it is contained, and leads to the parent of the ROOT directory, which is (special case) also ROOT. ROOT is the only directory that is its own parent. Thus, /../tmp is the same as /tmp. Similarly, the pathname /../../../../../tmp is also the same as /tmp.

If any of the pathname components are symbolic links to directories, not real directories, then the actions of “.” and “..” are not so well behaved and the answers may differ from those given above. (We won’t cover symbolic links here.) The ROOT directory can never be a symbolic link; so, /. and /.. (and /./. and /../../.., etc.) are always the same as / all by itself.

9 Relative Pathnames Exercise Index up to index

Given this absolute pathname to the file “file.txt”:

/home/user/lab/foo/bar/file.txt

Show how to rename “file.txt” to be “file2.txt” using a relative pathname, using as a starting point (a current directory) every directory from the “bar” directory up the tree to the ROOT directory.

Show how the relative pathnames change depending on the current working directory.

9.1 Answer Index up to index

The absolute file pathname /home/user/lab/foo/bar/file.txt contains six slashes, so it must have seven name components. The six name components to the left of the rightmost slash must be existing directories. There are six directories to the left of the final slash: ROOT, home, user, lab, foo, and bar.

We will start our answer in the “bar” directory and work our way up to the ROOT directory:

1. If the current working directory is "bar", then a relative path to
   file.txt from the "bar" directory is simply "file.txt", e.g.
    $ pwd
    /home/user/lab/foo/bar
    $ mv file.txt file2.txt

The file.txt relative pathname, used with a current working directory of /home/user/lab/foo/bar, means /home/user/lab/foo/bar/file.txt.

The file2.txt relative pathname, used with a current working directory of /home/user/lab/foo/bar, means /home/user/lab/foo/bar/file2.txt.

Now, go up one directory, from “bar” to its parent directory “foo”:

2. If the current working directory is "foo", then a relative path to
   file.txt from the "foo" directory is "bar/file.txt", e.g.
   $ cd ..
   $ pwd
   /home/user/lab/foo
   $ mv bar/file.txt bar/file2.txt

The bar/file.txt relative pathname, used with a current working directory of /home/user/lab/foo, means /home/user/lab/foo/bar/file.txt.

The bar/file2.txt relative pathname, used with a current working directory of /home/user/lab/foo, means /home/user/lab/foo/bar/file2.txt.

Now, go up one directory, from “foo” to its parent directory “lab”:

3. If the current directory is "lab", then a relative path to file.txt
   from "lab" is foo/bar/file.txt, e.g.
   $ cd ..
   $ pwd
   /home/user/lab
   $ mv foo/bar/file.txt foo/bar/file2.txt

The foo/bar/file.txt relative pathname, used with a current working directory of /home/user/lab, means /home/user/lab/foo/bar/file.txt. Similar for foo/bar/file2.txt.

Now, go up one directory, from “lab” to its parent directory “user”:

4. If the current directory is "user", then a relative path to file.txt
   from "user" is lab/foo/bar/file.txt, e.g.
   $ cd ..
   $ pwd
   /home/user
   $ mv lab/foo/bar/file.txt lab/foo/bar/file2.txt

As with the previous examples, to find out the full pathname, concatenate the relative path to the end of the current working directory.

Now, go up one directory, from “user” to its parent directory “home”:

5. If the current directory is "home", then a relative path to file.txt
   from "home" is user/lab/foo/bar/file.txt, e.g.
   $ cd ..
   $ pwd
   /home
   $ mv user/lab/foo/bar/file.txt user/lab/foo/bar/file2.txt

Now, go up one directory, from “home” to its parent directory the ROOT:

6. If the current directory is the ROOT then a relative path to file.txt
   from the ROOT is home/user/lab/foo/bar/file.txt, e.g.
   $ cd ..
   $ pwd
   /
   $ mv home/user/lab/foo/bar/file.txt home/user/lab/foo/bar/file2.txt

The home/user/lab/foo/bar/file.txt relative pathname, used with a current working directory of / (ROOT), means /home/user/lab/foo/bar/file.txt.

Note that in every case above, the output of “pwd” (the current directory) when prefixed to the beginning of the relative path, gives the absolute path, e.g. in #5 above, the current directory /home prefixed to the relative pathname user/foo/bar/file.txt gives the absolute path /home/user/lab/foo/bar/file.txt – this is how current directories let us write shorter relative pathnames.

Your current working directory is NOT prefixed to absolute pathnames (which start with a slash). Absolute pathnames always start at the ROOT and are always independent of your current working directory. Your current working directory is ONLY prefixed to relative pathnames (names that do not start with a slash).

10 Redundant but useful ./ prefix Index up to index

Putting ./ in front of any relative pathname does not change what the pathname refers to; the pathname is still relative to the current directory and still refers to the same thing.

Given directory dir1, these pathname arguments are all valid and all refer to the same directory dir1:

$ ls dir1
$ ls ./dir1
$ ls ././dir1
$ ls ./././dir1

Given file name file1, these pathname arguments are also valid and all refer to the same file file1:

$ ls file1
$ ls ./file1
$ ls ././file1
$ ls ./././file1

If you create a file (or directory) with a name starting with a dash, e.g. named “-r”, the file name cannot be removed without some trickery, since the name looks like an option to the “rm” (or “rmdir”) command:

$ rm -r
rm: missing operand
Try 'rm --help' for more information.

$ rmdir -r
rmdir: invalid option -- 'r'
Try 'rmdir --help' for more information.

You can put the redundant “./” in front of the name to make the name stop looking like an option letter:

$ rm ./-r
-OR-
$ rmdir ./-r

11 Understanding Pathnames Exercises Index up to index

Given this current working directory:

$ pwd
/tmp/idallen

and this sub-structure in the current directory:

$ ls -l
drwxr-xr-x    2 idallen  idallen      4096 Feb  3 20:33 dir1
-rw-r--r--    1 idallen  idallen         0 Feb  3 20:33 file1

Note that I have created name “dir1” as a directory and name “file1” as a file for all the examples below, though I could have called them any names.

All the relative pathnames below give the same output, because all these relative pathnames refer to the same (current) directory:

$ pwd
/tmp/idallen
$ ls
$ ls .
$ ls ./.
$ ls ././././././.
$ ls dir1/..
$ ls ./dir1/..
$ ls dir1/../.
$ ls dir1/../././././.
$ ls ../idallen
$ ls ./../idallen/./././.
$ ls ../../tmp/idallen
$ ls ../idallen/dir1/..
$ ls ../idallen/dir1/.././././.
$ ls dir1/../../idallen
$ ls ./dir1/../../idallen/.

All the absolute pathnames below also give the same output, because all these absolute pathnames refer to the same (/tmp/idallen) directory:

$ ls /tmp/idallen
$ ls /tmp/idallen/././.
$ ls /tmp/idallen/dir1/..
$ ls /tmp/../tmp/idallen/../idallen/dir1/..
$ ls /././tmp/./././../tmp/./././idallen/./././../././idallen/./dir1/./..

All the relative pathnames below give the same output, because all these relative pathnames refer to the same sub-directory “dir1”:

$ pwd
/tmp/idallen
$ ls dir1
$ ls dir1/.
$ ls ./dir1
$ ls ./dir1/.
$ ls ././././dir1/././././.
$ ls ../idallen/dir1
$ ls ../idallen/dir1/../dir1/.
$ ls ../../tmp/idallen/dir1/../../idallen/dir1/.

All the absolute pathnames below give the same output, because all these absolute pathnames refer to the same sub-directory “/tmp/idallen/dir1”:

$ ls /tmp/idallen/dir1
$ ls /tmp/../tmp/idallen/dir1
$ ls /tmp/../tmp/idallen/../idallen/dir1
$ ls /tmp/../tmp/idallen/../idallen/dir1/../dir1
$ ls /././tmp/./././idallen/./././dir1/./.

All the relative pathnames below give the same output, because all these relative pathnames refer to the ROOT directory (from /tmp/idallen):

$ pwd
/tmp/idallen
$ ls ../..
$ ls ../../../../..
$ ls dir1/../../..
$ ls dir1/../dir1/../../..
$ ls ../idallen/../..
$ ls ../../tmp/..
$ ls ../../tmp/idallen/../..
$ ls ../../tmp/idallen/../../tmp/idallen/../../././././.

All the absolute pathnames below give the same output, because all these absolute pathnames refer to the ROOT directory:

$ ls /
$ ls /.
$ ls /./././.
$ ls /tmp/..
$ ls /tmp/idallen/../..
$ ls /tmp/../tmp/idallen/../..
$ ls /tmp/idallen/dir1/../../..

All these commands copy the file “file1” into “file2” in the same (current) directory of “/tmp/idallen”:

$ pwd
/tmp/idallen
$ cp file1 file2
$ cp ./file1 ./file2
$ cp ././././././file1 ././././././file2
$ cp file1 ../idallen/file2
$ cp ../idallen/file1 file2
$ cp ../idallen/file1 ../idallen/file2
$ cp ../../tmp/idallen/file1 file2
$ cp file1 ../../tmp/idallen/file2
$ cp ../../tmp/idallen/file1 ../../tmp/idallen/file2
$ cp ./././././../../tmp/idallen/file1 ./././././../../tmp/idallen/file2
$ cp /tmp/idallen/file1 /tmp/idallen/file2
$ cp /tmp/../tmp/idallen/file1 /tmp/idallen/../idallen/file2
$ cp file1 /tmp/idallen/../../tmp/idallen/file2
Author: 
| Ian! D. Allen  -  idallen@idallen.ca  -  Ottawa, Ontario, Canada
| Home Page: http://idallen.com/   Contact Improv: http://contactimprov.ca/
| College professor (Free/Libre GNU+Linux) at: http://teaching.idallen.com/
| Defend digital freedom:  http://eff.org/  and have fun:  http://fools.ca/

Plain Text - plain text version of this page in Pandoc Markdown format


Campaign for non-browser-specific HTML   Valid XHTML 1.0 Transitional   Valid CSS!   Creative Commons by nc sa 3.0   Hacker Ideals Emblem   Author Ian! D. Allen