# Linux: Link ## Overview Link is creating another reference to a given file. There are 2 types of link within the file system - hard link - soft link (symbolic link, or symlink) ## Hard link **Usage** ```shell= $ ln target path ``` The file is represented as an **inode** in the disk. Hard link will create another `dirent` in the parent directory of `path` pointing to the inode of `target` file. ``` shell= $ pwd /home/kch $ mkdir foo && cd foo $ touch f $ ln f fh $ ls -li total 0 2422867 -rw-rw-r-- 2 kch kch 0 5月 22 02:05 f 2422867 -rw-rw-r-- 2 kch kch 0 5月 22 02:05 fh ``` As we can see both `f` and `fh` has the same inode number `2422867`. ## Soft Link **Usage** ```shell= $ ln -s target path ``` Soft link will create a new inode at `path` whose data stores the path of `target`. Note that `target` can be any string (even if it means nothing at all), and we can interpret the `target` in two ways. ### Absolute target When the `target` starts with `/`, we will interpret it as an absolute path. ``` shell= $ pwd /home/kch $ mkdir foo && cd foo $ mkdir bar && touch bar/f $ tree . . └── bar └── f $ ln -s /home/kch/foo/bar/f fs $ ls -l total 4 drwxrwxr-x 2 kch kch 4096 5月 22 02:12 bar lrwxrwxrwx 1 kch kch 19 5月 22 02:13 fs -> /home/kch/foo/bar/f ``` The `path = /home/kch/foo/fs` is a new inode whose data blocks contains the `target` path. ### Relative target If the `target` doesn't start with `/`, we will interpret `target` as relative path, and it is easy to be confused with the "relative" term (i.e. relative to what?). Let's look an example, and the setup is the same as the example of absolute path. ```shell= $ pwd /home/kch $ mkdir foo && cd foo $ mkdir bar && touch bar/f $ tree . . └── bar └── f $ ln -s bar/f fs $ ls -l total 4 drwxrwxr-x 2 kch kch 4096 5月 22 02:19 bar lrwxrwxrwx 1 kch kch 5 5月 22 02:21 fs -> bar/f ``` We can see that stores `bar/f` in `fs`, and how does it find the actual `f` file? Let's see the full path of the softlink. ```shell= $ readlink -f fs /home/kch/foo/bar/f ``` We can break the output into two parts - parent directory of `path`: `/home/kch/foo` - target relative path: `bar/f` If we move `fs` into `bar` ```shell= $ mv fs bar $ ls -l total 0 -rw-rw-r-- 1 kch kch 0 5月 22 02:19 f lrwxrwxrwx 1 kch kch 5 5月 22 02:25 fs -> bar/f $ cat fs cat: fs: No such file or directory ``` `fs` is interpreted as `/home/kch/foo/bar/bar/f`, which is not a valid path. ## Reference 1. [Make a symbolic link to a relative pathname](https://unix.stackexchange.com/questions/10370/make-a-symbolic-link-to-a-relative-pathname) ###### tags: `Linux`