Four routes to one file
◈ 9 cardsAbsolute and relative pathnames for the same file from three vantage points, what `.`, `..` and `~` really are, and how to ask your own system for its filename limit.
One tree, no drive letters
Every file on a UNIX system hangs somewhere below a single root directory, written /. There are no drive letters. A second disk, a USB stick or a network share is mounted — attached to the one tree at some existing directory, its mount point — and from then on it is reached by an ordinary pathname. A user need never know which physical device holds a file, and that unified namespace is the whole benefit of mounting.
A pathname is the route through that tree. It comes in two flavours, and the exam wants you fluent in both.
- An absolute pathname starts at the root:
/home/ada/proj/a.c. It begins with/, and it means the same file no matter where you are standing when you type it. - A relative pathname starts at your present working directory — the directory the shell considers you to be in, printed by
pwd.proj/a.cmeans "from here, go intoproj, then takea.c". Change directory and the same string names a different file, or nothing at all.
Three names carry the tree's structure, and all three are real directory entries rather than shell tricks:
.is the directory itself...is its parent. (In/,..is/— the root is its own parent, which is what stops..from walking off the top.)~is not a directory entry. It is expanded by the shell to your home directory before the command ever runs, and~adaexpands to that user's home. A program that receives~/projas a literal argument gets a directory named~, which almost certainly does not exist. That is the reason it must always be unquoted.
Worked example — one file, four pathnames, three vantage points
Ada's home is /home/ada and the file is /home/ada/proj/a.c. Start inside proj, and prove where you are standing before every claim:
$ pwd
/home/ada/proj
$ ls a.c # relative: from here
$ ls ./a.c # the same, said explicitly
$ ls ../proj/a.c # up to /home/ada, back down into proj
$ ls /home/ada/proj/a.c # absolute: true from anywhere
All four name the same bytes. Now walk to the parent and re-check which of them still work:
$ cd ..
$ pwd
/home/ada
$ ls proj/a.c # relative names shift with you
$ ls ~/proj/a.c # the shell rewrites ~ to /home/ada
$ ls /home/ada/proj/a.c # unchanged
And from somewhere else entirely:
$ cd /tmp
$ ls a.c # ls: cannot access 'a.c': No such file or directory
$ ls ~/proj/a.c # still fine — ~ does not depend on where you are
The lesson is not that one form is better. It is that an absolute pathname names a file; a relative pathname names a file plus a place to stand from. When a script fails on somebody else's machine, a relative path that assumed a working directory is the first thing to suspect.
How long may a filename be?
The kernel allows almost any byte in a filename, but there is a length limit, and the limit is a property of the file system, not of the machine — one mounted file system may permit 255 bytes while another permits fewer. So the question "what is the maximum filename length on your system?" is only answerable about a particular place in the tree, and the command that answers it takes a pathname argument:
$ getconf NAME_MAX /
255
$ getconf NAME_MAX /tmp
255
Historically System V allowed 14 characters and BSD raised it to 255; Linux and the modern BSDs are all in the 255 camp, and that is what you will see. Do not confuse it with PATH_MAX, the limit on a whole pathname, which is typically 4096 — a filename of 255 bytes is legal in a path that is nonetheless too long to use.