Symlinks
Autodereferenced references to filenames
A symlink is literally a text file that's treated specially by the kernel and whose contents is a path to another file/directory.
You can read the contents of a symlink file with readlink
, and if you standardly open a symlink file, the system will open the file/directory referenced by contents of the symlink.
Pointer/C++ reference analogy
If you're familiar with C/C++, then a symlink behaves somewhat like a C++ reference or an autodereferenced pointer in most contexts (not all: e.g., rm
or mv
work directly on the symlink, not on the target). The difference is that real C++ references bind to memory addresses whereas symlinks bind to filesystem addresses.
Dangling symlinks
The contents of a symlink don't have to be a valid filepath reference --> then you have a dangling symlink (like danglig pointer or a dangling reference).
Relative symlinks
If the filepath in a symlink isn't an absolute one (starting with /
), then the relative filepath is resolved relatively to the location of the symlink (in non-symlink contexts, relative paths are resolved relatively to the $PWD
).
The -s Flag and Hardlinks
The -s
flag is for "create symlinks". ln
can also create hardlinks.
Hardlinks operate at another level, which is closer to the implementation of the filesystem (consequently, you cannot create hardlinks across different filesystems).
Unix filesystems store filenames(/directory names) and file contents (directory contents) separately, and names are just autodereferenced reference-counted pointers to their contents. A hardlink creates another name for the same contents while increasing the reference count.
$ echo 'the contents' > f1
$ ls -l f1
* 1 * #the 2nd column is the reference count
$ ln f1 f2 #create another name for the contents of f1
$ ls -l f1
* 2 * #the contents of f1 has two named references to it
$ rm f1 #the contents of f1 lives on (in f2) #
# because rm only removes the reference to the data block
#and this isn't the only reference
#(rm ivokes a system call literally named `unlink`)
Directory hardlinks
You can't create directory hardlinks, but .
and ..
are directory hardlinks implicitly created for you. Consequently the hardlink count for a directory reflects how many subdirectories it has (each subdirectory comes with a ..
hardlink to the parent).
Symlinks and Hardlinks—Big Picture Overview:
echo 'file data' > fileName
ln fileName fileName2 #hardlink
ln -s "$PWD/fileName" absoluteSymlinkTofileName
ln -s fileName relativeSymlinkTofileName
On the same physical file system, ln
creates another name for file data
(ln
will fail across filesystems). You can delete either fileName
or fileName2
and as long as at least one name remains, file data
lives on.
absoluteSymlikTofileName
is an autodereferenced reference to the fileName
name. As long as that path resolves to something, the symlink is valid. If you delete the target, the symlink dangles. This is an absolute symlink so you can move it to other places without changing its validity.
relativeSymlinkToFileName
refers to a name called fileName
in the same directory as the directory of relativeSymlinkToFileName
. If you move it to another directory that also has a file (or directory) named fileName
, then it'll point to that instead.