Tuesday Tiny Techie Tip

Links

ln(1) creates a "link" to a file. To know what that means, you need to know a little bit about how the UNIX filesystem works. (note, I'm doing this off the top of my head without references, so if you want to go write your own UNIX filesystem, you might want to double check my misconceptions).

In the UNIX filesystem, everything is a file. Even directories are files. The directory file is a list of references to the files which are "in" that directory. The directory file also contains the names of the files. The references are numbers called inodes. inodes are references to a part of a disk partition. You can see the actual inodes associated with files by using the "-i" flag to ls(1):


% ls -lai
total 98
178560 drwxrwxr-x  3 jeffy         512 Dec  9 13:19 .
7332480 drwxrwxr-x  3 jeffy         512 Dec  9 13:15 ..
178564 -rw-r--r--  1 jeffy         277 Dec  9 13:18 Makefile
178563 -rw-r--r--  1 jeffy       11296 Dec  9 13:18 bar.c
178561 -rw-r--r--  1 jeffy       61856 Dec  9 13:18 foo.c
178562 -rw-r--r--  1 jeffy       21213 Dec  9 13:18 foo.h
180480 drwxrwxr-x  2 jeffy         512 Dec  9 13:18 hold

The number at the beginning of each line is the inode associated with that file. Notice that the directories have inodes too. Also notice that if we look into the "hold" subdirectory:
% ls -lai hold
total 63
180480 drwxrwxr-x  2 jeffy         512 Dec  9 13:23 .
178560 drwxrwxr-x  3 jeffy         512 Dec  9 13:19 ..
180481 -rw-r--r--  1 jeffy       61856 Dec  9 13:23 foo.c

the inode for the "." directory inside "hold" is the same as the inode for "hold" up in its parent directory. In other words, they are both references to the same file. (This is what allows you to use "." as a shorthand for the current directory)

ln(1) allows you to add two different kinds of file references into directories.

Symbolic Links

The most commonly used kind of reference created by ln is what is called a symbolic link. This type of link is created using the "-s" flag to ln. Creating a symbolic link (sometimes called "soft link", or just "symlink") actually creates a new file in the directory which contains a reference to another file.
% ln -s bar.c barsym.c
% ls -li bar*
178563 -rw-r--r--  1 jeffy       11296 Dec  9 13:18 bar.c
178565 lrwxrwxrwx  1 jeffy           5 Dec  9 13:33 barsym.c -> bar.c

The ls command (and the rest of the UNIX toolset) knows about symlinks and shows them specially in its long output, indicating the name of the link itself and a pointer to the file being referenced: "link -> real/file"

Notice that the link has its own inode since it is an actual file. The size of the link file is the length of the filename it points to. (The string "bar.c" is five characters long)

There are no restrictions on what a symlink can point to. It can look at another file in the same directory (foo.c), in a different directory by relative (../foo.c), or absolute (/home/jeffy/foo.c) path, in the local filesystem or another filesystem. The symlink doesn't even have to point at an existing file, so if I had made a typo in creating that link, it would have been created looking for the non-existant file:


% ln -s bart.c bartsym.c
% ls -li bar*
178563 -rw-r--r--  1 jeffy       11296 Dec  9 13:18 bar.c
178565 lrwxrwxrwx  1 jeffy           5 Dec  9 13:33 barsym.c -> bar.c
178566 lrwxrwxrwx  1 jeffy           6 Dec  9 13:47 bartsym.c -> bart.c
% cat bartsym.c
cat: bartsym.c: No such file or directory

Notice that the message here is kind of confusing in that it says the name of the link (bartsym.c) doesn't exist when what it means is that the link points to something that doesn't exist. If you had done just a regular ls to see the filename before trying to cat it, this message would be very confusing to you:
% ls bar*
bar.c           barsym.c        bartsym.c
% cat bartsym.c
cat: bartsym.c: No such file or directory

This is where the "-F" flag to ls(1) comes in handy. That flag causes ls to append a character to filenames whose files are special in some way. as follows:
file/=>file is a directory
file*=>file is executable
file@=>file is a symbolic link
So if you used ls -F:
% ls -F bar*
bar.c           barsym.c@       bartsym.c@
% cat bartsym.c
cat: bartsym.c: No such file or directory

you at least have a clue why the cat failed.

This lack of connection between the link and the file linked to means that even if the file pointed to existed when the link was created, there's no guarantee that it will still exist when you get around to trying to reference it. You can check whether the linked-to thing exists by using the "-L" flag to ls(1). This flag tells ls to show information about the referenced file (if it exists) instead of the link itself.


% ls -liL bar*
178563 -rw-r--r--  1 jeffy       11296 Dec  9 13:18 bar.c
178563 -rw-r--r--  1 jeffy       11296 Dec  9 13:18 barsym.c
178566 lrwxrwxrwx  1 jeffy           6 Dec  9 13:47 bartsym.c -> bart.c

In the example, ls followed the barsym.c link and returned all the information (except the name) about that file (including its inode) instead of the information about the link. Since bart.c doesn't exist, we get the information about the bartsym.c link itself.

In the ln(1) man page, there are some valuable warnings about the somewhat unexpected things that can happen when you deal with symlinks to directories. I won't recreate them here.

Hard Links

So symbolic links are basically textual references to another file by name (path included).

The other kind of link (and the default) is called a hard link.

The hard link is a second reference to an existing inode.


% ls -li *r.c
178563 -rw-r--r--  1 jeffy    se          11296 Dec  9 13:18 bar.c
% ln bar.c hardbar.c
% ls -li *r.c
178563 -rw-r--r--  2 jeffy       11296 Dec  9 13:18 bar.c
178563 -rw-r--r--  2 jeffy       11296 Dec  9 13:18 hardbar.c

A couple of things to notice here. First, notice that both bar.c and hardbar.c have the same inode. That means they are references to the same physical disk location. Also notice the third column of the ls -li output. This column shows the link count for the referenced inode. Before the ln operation, there is only one link to the inode associated with bar.c. After the ln operation there are two references (and since hardbar.c has the same inode, it shows two links to it as well).

There are three restrictions on the creation of hard links.

  1. Since the reference is to an inode, and inodes are only meaningful within their disk partition, it is not possible to have a hard link to a file in another partition.
  2. The file being linked to must exist when the link is created (you can't create a second link to nothing).
  3. Only the superuser can create a hard link to a directory.
    (It's a good thing, too. I did it once ("What do you mean, I can't create a link to a directory?! Watch this!") and never did figure out how to undo it. The main problem is ".." - if you reference the same directory from two different directories, where does ".." point when you're in that directory? Confused kernel. Confused tools. Confused (ex)sysadmin. To make a long parenthetical even longer, note that in a Clearcase multi-version filesystem, this limitation does not exist since the MVFS is not strictly treelike (as anyone who's ever ventured to do a "cd .@@/main/LATEST" followed by a "cd ../../.." can attest. (You're not in "." anymore!)))

Final note on hard links: look what happens when we remove the original file:
% ls -li *r.c
178563 -rw-r--r--  2 jeffy       11296 Dec  9 13:18 bar.c
178563 -rw-r--r--  2 jeffy       11296 Dec  9 13:18 hardbar.c
% rm bar.c
% ls -li *r.c
178563 -rw-r--r--  1 jeffy       11296 Dec  9 13:18 hardbar.c

It shouldn't be any surprise that when we had two references to inode 178563 and we deleted one, we end up with one reference to that disk location. The contents were not deleted, just one of the references.

For your own amusement, explain the following:


% mkdir foo
% mv foo ~q345/Source
mv: can't mv directories across file systems


Tuesday Tiny Techie Tip -- 10 December 1996
Forward to (12/17/96)
Back to (12/03/96)
Written by Jeff Youngstrom

Up to the TTTT index

Tuesday Tiny Techie Tips are all © Copyright 1996-1997 by Jeff Youngstrom. Please ask permission before reproducing any of this material.