Winter 2017 - January to April 2017 - Updated 2019-01-06 04:23 EST
Unix/Linux files are organized within a single-tree hierarchical file system structure made up of files containing data (e.g. documents, programs), and directories (folders) that may contain other sub-directories and files.
Unlike Windows with separate multiple drive letters (A:
, B:
, C:
, etc.) for each disk partition, the Unix/Linux file system hides the physical disk structure and has a single tree root, no matter how many disks or partitions are actually in use. There is no way to tell on what disk partition a Unix/Linux file resides by looking at its name.
The directory structure in the file system is “acyclic” – following a path of directories down from the tree root into sub-directories will never lead you back toward the tree root into a “cycle” or loop.
Symbolic Links are special types of pointer files that can be used to point anywhere in the file system, so programs that follow symbolic links may get into cycles or loops. l> If you ignore symbolic links, the file system has no cycles or loops.
Each file and directory has its own name.
The name of some object in the file system may contain any characters except the NUL character and forward slashes (/
). The name may contain spaces, newlines, unprintable control characters, and characters from non-English languages.
Yes, you can have a file or directory name that is entirely made of blanks or backspace characters!
A single Linux name component is typically limited to 255 characters. Older Unix systems may have smaller limits.
A Unix/Linux pathname is a text string made up of one or more names separated by forward slashes (/
), e.g. /etc/passwd
, /var/log/auth.log
, assignment02/check
, etc. A pathname is a path-of-names that indicates how to find something in the hierarchical file system tree. Here are some examples of pathnames:
/home
/etc/passwd
/usr/bin/wc
/var/log/ntpstats/loopstats
/home/abcd0001/CST8207-19F/Assignments/assignment02
assignment02/check
../../Assignments
A pathname is literally a “path of names” through the hierarchy. A pathname specifies how to traverse (navigate) the hierarchical directory names in the file system to reach some destination object.
The pathname text string will contain, in order, the directories you need to go through to arrive at the destination. To do this, the pathname text string lists one or more name components separated by forward slashes, e.g. /etc/passwd
, /usr/bin/wc
. This is why individual file and directory names cannot themselves contain slashes – slashes are used to separate the names in pathname text strings.
Slashes separate the names in pathname text strings.
The destination object identified by the name at the far right end of a pathname text string might be a file, a directory, or some other thing such as system memory, a disk partition, or a terminal device. (Unix/Linux also uses the file system to name many things that are not ordinary files or directories.)
In a valid pathname, all the names to the left of the name at the far right end must be directories (or symbolic links to directories). If foo/bar/x
is a valid pathname, then foo
and bar
must be directories.
A pathname with only one name component doesn’t need to have any slashes to separate it from other name components, e.g. resume
, cal.txt
, dir.exe
are valid names and don’t need any slashes.
Slashes are only used to separate name components in a pathname; an individual name component can never itself contain a slash. Slashes are never part of a name component; they separate the names in a pathname.
A Linux pathname text string has an overall limit of 4,096 characters including all the individual names and all the separating slashes. Older Unix systems have a smaller limit.
Unlike Windows, Unix/Linux file system name components are separated by forward slashes (
/
), not backslashes (\
). You can blame Microsoft for this annoying difference: Unix came first and Microsoft deliberately chose a different separator character, likely to avoid being sued by AT&T for copying the Unix file system naming.You will note that Internet World-Wide-Web URL pathnames use the Unix forward slash separator (e.g.
http://teaching.idallen.com/
, because the web was invented and grew up on Unix machines.
Consider the following Unix/Linux pathname text string, composed of several individual name components separated by forward slashes:
/home/idallen/bin/file.txt
Since slashes always separate name components, a pathname with four slashes in it must contain and separate five name components. In this example above, those five name components are:
home
idallen
bin
file.txt
Yes, there is actually an implied directory to the left of the leftmost slash in a pathname that starts with a slash! It is the nameless “ROOT” directory, the unique tree root of the whole hierarchical file system tree, where all pathnames originate.
/
has no nameIndexSlashes always separate name components. If a pathname starts with a slash, e.g. /etc/passwd
, the nameless “ROOT” directory is what begins the pathname at the far left end. This top-most ROOT directory itself has no name. It is the starting point or the tree root of the entire hierarchical Unix/Linux file system tree.
A pathname starting with a slash is called an absolute pathname. It always starts at the unique topmost file system ROOT directory.
/
IndexBecause 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 technically wrong, because name components of a pathname can’t contain slashes – the slashes separate the name components. So nothing can have an actual name of /
. Still, we often call the topmost ROOT directory slash (/
).
Understand that when we use the name slash (/
) for ROOT, we really mean “the nameless topmost ROOT directory that is to the left of the separating slash”, not the slash itself.
NOTE! Do not confuse the topmost file system ROOT directory, that has no name, with an actual directory named
/root
that is usually the HOME directory of the system account namedroot
. In these notes we use upper-case ROOT to refer to the root of the file system, and justroot
to refer to a directory namedroot
.
To be a valid pathname (“path of names”) in the file system, every name component that is to the left of the rightmost slash in a pathname must either be a directory or be a symbolic link to a directory.
Only directories can have substructure that may lead to other names.
If the pathname /home/idallen/bin/file.txt
is to be a valid path of names through the file system hierarchy, the first four name components (the ROOT, home
, idallen
, and bin
) must name existing directories. Only directories can contain and lead to other names. The four name components to the left of the rightmost slash must be names for existing directories (or be symbolic links to existing directories).
In /home/idallen/bin/file.txt
, 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 file or directory or anything else, though the name file.txt
suggests that it is a text file name.
The final named component in the pathname, after the rightmost slash, can name anything – a file, directory, symbolic link, or other special file.
If a pathname ends in a directory name followed by a slash at the right end, e.g. /usr/bin/
or dir/
, the self-referential name .
(dot, or period) is assumed after the ending slash. In a directory, .
refers to the directory itself. For example, all these are equivalent:
$ ls /bin
...many names print here...
$ ls /bin/
...same names print here...
$ ls /bin/.
...same names print here...
Putting one or more slashes at the right end of a directory pathname makes almost no difference – it usually refers to the same directory:
$ ls /bin
...many names print here...
$ ls /bin/
...same names print here...
$ ls /bin//
...same names print here...
$ ls /bin////////////////////////////////
...same names print here...
In most pathnames ending in a directory name dir
, all the names dir
and dir/
and dir/.
refer to the same dir
directory. The trailing slash or slash-plus-dot don’t make any difference.
If the last name component in a pathname is a symbolic link to a directory, e.g.
/dir/symlink
, trailing slashes may result in different behaviour with some commands. More on symbolic links later.
By convention, multiple adjacent slashes are treated as one slash and do not create additional implied names. The pathnames /etc/passwd
and ///etc///////passwd
are equivalent.
A name component that names a file cannot be followed by a slash in a valid pathname. Only a directory name can have a slash to its right, because only directories can contain and lead to other names.
Putting a slash to the right of a non-directory (e.g. a file) results in an invalid pathname. Here is an example using the file pathname /etc/passwd
:
$ wc /etc/passwd
37 89 1802 /etc/passwd # expected command output
$ wc /etc/passwd/
wc: /etc/passwd/: Not a directory # error message!
$ wc /etc/passwd/.
wc: /etc/passwd/.: Not a directory # error message!
$ wc /etc/passwd/..
wc: /etc/passwd/..: Not a directory # error message!
In a directory named /tmp/dir
, the pathname /tmp/dir/../dir
is the same as /tmp/dir
, but if /tmp/f
is a file name, the pathname /tmp/f/../f
is invalid: Not a directory.
You can’t put a slash after a file name component, because the file name component isn’t a directory that leads to other names. You can’t use a file name as if it were a directory. The error message tells you this.
basename
IndexDefinition of basename: The basename of any pathname is its right-most name component, to the right of its right-most slash.
/home/user/file
has a basename of file
/usr/lib/file
has a basename of file
/etc/file
has a basename of file
/bin/grep
has a basename of grep
bin/grep
has a basename of grep
./grep
has a basename of grep
grep
has a basename of grep
bin/.
has a basename of .
/etc/..
has a basename of ..
lib/
has an empty basenameSeveral different files with the same basename can exist on a Unix/Linux system, in different directories (as in the example above of /home/user/file
and /usr/lib/file
that have the same basename but reside in different directories).
Pathnames come in two flavours: absolute and relative:
/etc/passwd
, /var/log/auth.log
, /bin/ls
, etc.etc/passwd
, ./check
, ../Assignments
, etc./
IndexA pathname that starts with a leading slash on the left is called an absolute pathname, e.g. /etc/passwd
, /root/.bashrc
, /bin
, /
, etc.
The leading slash on the left indicates that the pathname starts at the topmost nameless ROOT directory in the file system.
An absolute pathname traverses the file system hierarchy tree from the very top, always starting at the topmost ROOT directory of the file system hierarchy. The topmost ROOT directory is signalled by the leading “slash” character (/
) at the start of an absolute pathname.
Absolute pathnames always start with this topmost ROOT directory slash and descend through every directory name that leads down to the destination, e.g. /home/user/file
or /usr/bin/grep
or /bin/ls
or /etc/passwd
.
The slash must always be at the start (left) of an absolute pathname.
Pathnames with no leading slash on the left are called relative pathnames.
A relative pathname never starts with a slash on the left, but it may contain slashes anywhere else: /bar
is not relative (it is an absolute pathname) but bar
and bar/
and ./bar
and ../bar
and foo/bar
are all relative pathnames.
A relative pathname is used along with the current working directory to avoid typing long pathnames.
To save typing long pathnames all the time, many operating systems (including Unix/Linux and DOS) have the concept of a saved current working directory, also called current directory or working directory.
Every process in Linux can save one absolute directory pathname to be its current working directory. This working directory can be set and changed in shells using the built-in cd
(change directory) command, e.g. cd /home/idallen
. The current working directory can be displayed in shells using the pwd
(print working directory) command:
$ pwd
/home/idallen
$ cd /usr/bin
$ pwd
/usr/bin
$ cd
$ pwd
/home/idallen
If a process refers to a pathname that is relative (does not start with a slash), the saved current directory is always automatically prefixed to (“inserted in front of”) the beginning of the pathname.
For example, if the current working directory of a process is the absolute pathname /usr/bin
then all relative pathnames used by the process have /usr/bin
prefixed in front of them:
/usr/bin
relative pathname foo
is the same as as: /usr/bin/foo
/usr/bin
relative pathname ../etc
is the same as as: /usr/bin/../etc
/usr/bin
relative pathname ./hello
is the same as as: /usr/bin/./hello
/usr/bin
relative pathname .
(dot) is the same as as: /usr/bin/.
/usr/bin
absolute pathname /bin
is unchanged, since it is not a relative pathname.If you then change the current working directory of the process to be the absolute pathname /home
then all relative pathnames used by the process now have /home
prefixed in front of them instead:
/home
relative pathname foo
is the same as: /home/foo
/home
relative pathname ../etc
is the same as: /home/../etc
/home
relative pathname ./hello
is the same as: /home/./hello
/home
relative pathname .
(dot) is the same as: /home/.
/home
absolute pathname /bin
is unchanged, since it is not a relative pathname.The saved current directory of a process is only prefixed to relative pathname references – pathnames that do not start with a slash. Absolute pathnames (starting with a slash) are not affected.
Changing the saved current directory of a process changes the meaning of relative pathnames used by the process. You don’t know what relative path foo
means until you know what saved current directory is going to be prefixed in front of it.
The saved current working directory of a process has no effect on an absolute pathname. An absolute pathname always starts at the ROOT and doesn’t depend on the saved current directory of a process. The current directory is not used when evaluating absolute pathnames. Absolute pathname
/etc/passwd
always always refers to the same file, no matter what the current directory of a process might be.
Shells have change directory commands that let you change the saved current working directory of the shell, and of all the commands run by the shell, so that you can then type shorter relative pathnames, instead of always using long absolute pathnames. The shell change directory command is often named cd
, e.g.: cd /usr/bin
Saving an appropriate current working directory prefix and using relative pathnames can make using pathnames in shell command lines much shorter to type. For example, to copy file /usr/bin/foo
to /usr/bin/bar
looks like this when using absolute pathnames in a shell command line:
$ cp /usr/bin/foo /usr/bin/bar # using two absolute pathnames
Setting an appropriate current working directory with cd
and switching to using relative pathnames in the copy command makes the command much simpler to type:
$ cd /usr/bin
$ cp foo bar # two relative pathnames each use current directory
The relative pathname foo
automatically becomes /usr/bin/foo
and the relative pathname bar
automatically becomes /usr/bin/bar
thanks to the saved current working directory /usr/bin
being prefixed to each pathname.
The saved current working directory is only prefixed to relative pathnames. Absolute pathnames remain unchanged.
Absolute pathnames always refer to the same, unique destination, since absolute pathnames always start with the topmost ROOT slash and don’t depend on the current directory of a process. Every process using an absolute pathname refers to the same, unique file system object, no matter what the current directory of the process is. For example, the absolute pathname /etc/passwd
(starting with the topmost ROOT slash) always means the same file anywhere it is used, ignoring the current directory. The current directory is ignored for absolute pathnames.
Relative pathnames always start in the saved current directory of a process, so the final destination changes depending on the current directory of the process. The same relative pathname may refer to different things in processes that have different current directories. Changing the current directory changes the final destination of the relative pathname.
If the saved current working directory of a process is /home/user
, and the absolute pathname of a file is /home/user/file
, then a relative pathname to that file (using the saved current directory prefix) is simply file
(no leading slash):
$ cd /home/user
$ cat file # relative path is same as /home/user/file
If the saved current working directory is changed to /home
, then a relative pathname to that same file (using the saved current directory prefix) must be user/file
:
$ cd /home
$ cat user/file # relative path is same as /home/user/file
If the current directory is changed to /
(the topmost ROOT), then the relative pathname to that same file (using the saved current directory prefix) must be home/user/file
:
$ cd /
$ cat home/user/file # relative path is same as /home/user/file
If your saved current working directory is the topmost ROOT directory, then absolute and relative pathnames look almost the same. The only difference is the leading slash on the absolute pathname:
$ cd /
$ cat home/user/file # relative path is same as /home/user/file
$ cat /home/user/file # equivalent absolute pathname
The saved current directory is prefixed to a relative pathname, resulting in an absolute pathname. A current directory of /home/user
plus a relative pathname of bin/script
equals an absolute pathname of /home/user/bin/script
.
To take an absolute pathname and turn it into a shorter relative pathname, using the saved current directory, take the absolute pathname and remove the current directory from the start, leaving a relative pathname (no leading slash). A current directory of /home/user
removed from the start of an absolute pathname /home/user/bin/script
leaves a relative pathname of bin/script
:
$ cat /home/user/bin/script # (too) long absolute pathname
$ cd /home/user # set working directory
$ cat bin/script # use shorter relative pathname!
$ cd /home/user/bin # set better working directory
$ cat script # use even shorter relative pathname!
One of the major reasons we use relative pathnames is because they are usually much shorter to type than absolute pathnames. Choose a good working directory to make your relative pathnames short.
~
, ~user
, and $HOME
may become AbsoluteIndexMost Unix/Linux 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, even though it is.
Here are some examples:
Shells may expand a leading tilde (~
) on a token (command argument) to be the absolute pathname to the user’s home directory:
$ echo ~
/home/user
$ echo ~/bar
/home/user/bar
$ cat ~/bar # same as cat /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).
Try this command line to see how the shell expands the tilde pathnames:
$ whoami
idallen
$ echo ~ ~/bin
/home/idallen /home/idallen/bin
If the tilde is followed by a valid account name, e.g. ~idallen
, the shell replaces the tilde and account name 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 for different account names:
$ echo ~mail ~uucp ~games ~root ~nosuch
/var/mail /var/spool/uucp /usr/games /root ~nosuch
Thus, ls ~idallen/bin
secretly expands to and uses an absolute pathname, because, ~idallen
is actually expanded (by the shell) to be the absolute path /home/idallen
. Be aware of this!
$HOME
variable may mean absoluteIndexAbsolute 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/idallen /home/idallen/bin
Thus, ls "$HOME/bin"
secretly expands to and uses an absolute pathname, because, $HOME
is actually expanded (by the shell) to be the absolute path /home/idallen
. Be aware of this!
The shells modify your command line before they call the command to be executed. These modifications can turn what look like relative pathnames (e.g. ~/bin
) into absolute pathnames (e.g. /home/idallen/bin
):
A pathname is absolute if and only if it starts with a leading slash after all shell expansions are finished. If the expanded pathname 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
.
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
in the same directory, using relative pathnames, using as a starting point (a current directory) every directory from the bar
directory up the tree to the topmost ROOT directory (giving six different answers, one for each different current working directory).
Show how the relative pathnames change depending on each of the six different current working directories.
If we were using absolute pathnames, the command to rename the file would be very long:
$ mv /home/user/lab/foo/bar/file.txt /home/user/lab/foo/bar/file2.txt
Below, we show how different saved current working directories make the pathname shorter.
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, giving six different answers:
/home/user/lab/foo/bar
IndexIf the current working directory is bar
(actually /home/user/lab/foo/bar
), then a relative path to file.txt
from the bar
directory is simply file.txt
, e.g.
$ cd /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
:
/home/user/lab/foo
IndexIf the current working directory is foo
(actually /home/user/lab/foo
), then a relative path to file.txt
from the foo
directory is bar/file.txt
, e.g.
$ cd /home/user/lab/foo # or use the parent directory: cd ..
$ 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
:
/home/user/lab
IndexIf the current directory is lab
(actually /home/user/lab
), then a relative path to file.txt
from lab
is foo/bar/file.txt
, e.g.
$ cd /home/user/lab # or use the parent directory: cd ..
$ 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
:
/home/user
IndexIf the current directory is user
, then a relative path to file.txt
from user
is lab/foo/bar/file.txt
, e.g.
$ cd /home/user # or use the parent directory: cd ..
$ 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
:
/home
IndexIf the current directory is home
, then a relative path to file.txt
from home
is user/lab/foo/bar/file.txt
, e.g.
$ cd /home # or use the parent directory: cd ..
$ 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:
/
(ROOT)IndexIf 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 / # or use the parent directory: cd ..
$ 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 saved 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 (that 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).
.
and ..
IndexEvery Unix directory contains two special names that you can’t change and can’t remove:
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.
/tmp/.
and /./tmp
IndexThe directory pathname /tmp
contains two directories: the leading topmost ROOT directory 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
/tmp/..
IndexThe 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/
. More on that later.
/home/idallen/bin/../..
IndexThe 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 equivalent to /home
(unless there are symbolic links involved).
Each ..
in a pathname backs up one directory level.
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.
The topmost 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.
/../tmp
and /../../../../../tmp
IndexThe 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
.
..
for shorter pathnamesIndexYou can use ..
to make shorter pathnames when typing. Here are three examples using the cp
(copy) command:
$ cp /usr/local/foo /usr/local/bin/ # 1. using absolute pathnames
$ cd /usr/local # 2. set current directory; use
$ cp foo bin/ # short relative pathnames
$ cd /usr/local/bin # 3. set current directory; use
$ cp ../foo . # short relative pathnames
From the current directory /usr/local/bin
, the pathname ../foo
is a relative path that goes up one level to /usr/local
and then down to foo
inside /usr/local
giving /usr/local/foo
. That file is copied into the current directory (/usr/local/bin
) using the relative pathname .
(/usr/local/bin/.
).
Using ..
and .
can shorten your pathnames considerably if you choose your current directory carefully.
./
prefixIndexPutting ./
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. Don’t do it.
Given directory dir1
, these pathname arguments are all valid and all refer to the same directory dir1
, so don’t add the ./
because it isn’t needed:
$ ls dir1 # use this
$ ls ./dir1 # same, but unnecessary
$ ls ././dir1 # same, but more unnecessary
$ ls ./././dir1 # same, but even more unnecessary
Given file name file1
, these pathname arguments are also valid and all refer to the same file file1
, so don’t add the ./
because it isn’t needed:
$ ls file1 # use this
$ ls ./file1 # same, but unnecessary
$ ls ././file1 # same, but more unnecessary
$ ls ./././file1 # same, but even more unnecessary
-r
)IndexIf 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, because the name looks like an option to the rm
(or rmdir
) command:
$ ls # show the files in the current directory
-r # a problem file named "-r" !
$ rm -r # WRONG: does not remove file named "-r"
rm: missing operand
Try 'rm --help' for more information.
$ rmdir -r # WRONG: does not remove directory named "-r"
rmdir: invalid option -- 'r'
Try 'rmdir --help' for more information.
The trick is: You can put the superfluous ./
in front of the relative pathname to make the name stop looking like an option letter:
$ rm ./-r # this works to remove a file named -r
-OR-
$ rmdir ./-r # this works to remove a directory named -r
Of course, you can also use the full absolute pathname that starts with a slash, since that doesn’t look like an option letter either.
$ rm /home/idallen/-r # this works! but it's long!
$ rmdir /home/idallen/-r # this works! but it's long!
./
in front of relative pathnamesIndexThe above option hiding tricks are the only reason to add ./
in front of a relative pathname. Don’t use ./
in front of a relative pathname unless you need to. This is superfluous:
$ touch ./foo # WRONG: ./ is not needed
$ touch foo # RIGHT
Relative pathnames do not start with a slash. Putting ./
in front of a pathname that does not start with a slash is unnecessary.
Below are some pathname exercises 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.
For the exercises below, assume none of the names are symbolic links (which could change the answers).
All the relative pathnames below give the same output, because all these relative pathnames refer to the same (current) directory /tmp/idallen
:
$ pwd
/tmp/idallen
$ ls # with no pathname arguments, ls lists the current directory
$ ls .
$ ls ./.
$ ls ././././././.
$ ls dir1/.. # the parent directory of dir1 is the current directory
$ ls ./dir1/..
$ ls dir1/../.
$ ls dir1/../././././.
$ ls ../idallen # go up to the parent, then back down into 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/./..
dir1
IndexAll the relative pathnames below give the same output, because all these relative pathnames refer to the same sub-directory /tmp/idallen/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/.
dir1
IndexAll 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 below 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