Classic Shell Scripting - Arnold Robbins [237]
Since the directory entry contains just an inode number, it can refer only to files within the same physical filesystem. We've already seen that Unix filesystems usually contain multiple mount points, so how can we make a link from one filesystem to another? The solution is a different kind of link, called a soft link, or symbolic link, or just symlink, to distinguish it from the first kind, called a hard link. A symbolic link is represented by a directory entry that points to another directory entry,[18] rather than to an inode entry. The pointed-to entry is given by its normal Unix pathname, and thus, may point anywhere in the filesystem, even across mount points.
Symbolic links make it possible to create infinite loops in the filesystem, so to prevent that, a chain of symbolic links is followed for only a few (typically, eight) steps. Here is what happens with a two-element loop:
$ ls -l
Show the link loop
total 0
lrwxrwxrwx 1 jones devel 3 2002-09-26 08:44 one -> two
lrwxrwxrwx 1 jones devel 3 2002-09-26 08:44 two -> one
$ file one
What is file one?
one: broken symbolic link to two
$ file two
What is file two?
two: broken symbolic link to one
$ cat one
Try to display file one
cat: one: Too many levels of symbolic links
For technical reasons (among them, the possibility of loops), directories normally cannot have hard links, but they can have symbolic links. The exceptions to this rule are the dot and dot-dot directory entries, which are created automatically when a directory is created.
Devices as Unix Files
One of the advances over earlier systems that Unix made was to extend the file notion to attached devices. All Unix systems have a top-level directory named /dev, underneath which are oddly named files like /dev/audio, /dev/sda1, and /dev/tty03. These device files are handled by special software modules, called device drivers, that know how to communicate with particular external devices. Although device names tend to be highly system-dependent, collectively they provide a convenient open-process-close access model similar to normal files.
* * *
Tip
The integration of devices into the hierarchical file system was the best idea in Unix. — Rob Pike et al., The Use of Name Spaces in Plan 9, 1992.
* * *
Entries in the /dev tree are created by a special tool, mknod, often hidden inside a shell script, MAKEDEV, and invariably requiring system-manager privileges to run: see the manual pages for mknod(1) and MAKEDEV(8).
Most Unix users only rarely refer to members of the /dev tree, with the exception of /dev/null and /dev/tty, which we described in Section 2.5.5.2.
In the 1990s, several Unix flavors introduced a random pseudodevice, /dev/urandom, that serves as a never-empty stream of random bytes. Such a data source is needed in many cryptographic and security applications. We showed in Chapter 10 how /dev/urandom can be used to construct hard-to-guess temporary filenames.
* * *
Files Without Names
A peculiarity of the Unix operating system is that the names of files that are opened for input or output are not retained in kernel data structures. Thus, the names of files that are redirected on the command line for standard input, standard output, or standard error are unknown to the invoked process. Think of it: we have a filesystem that might contain millions of files, yet exactly three of them cannot be named! To partially remedy this deficiency, some recent Unix systems provide the names /dev/stdin, /dev/stdout, and /dev/stderr, or sometimes less mnemonically, /dev/fd/0, /dev/fd/1, and /dev/fd/2. On GNU/Linux and Sun Solaris, they are also available as /proc/ PID /fd/0, and so on. Here is how to see whether your system supports them; you'll get either a successful run like this:
$ echo Hello, world > /dev/stdout
Hello, world
or a failure like this:
$ echo Hello, world > /dev/stdout
/dev/stdout: Permission denied.
Many Unix programs found the need for names for these redirected files, so a common convention is that