0

I've read this link, now I simply want to know why there are lots of hard link in /usr.

For example, in my Ubuntu server, installed git, I found the command git here: /usr/bin/git. I execute ls -l /usr/bin/git and get the output as below:

-rwxr-xr-x 119 root root 11178080 Mar  6 03:48 /usr/bin/git

As you see, there are 119 hard links...

Why do we need 119 hard links here? More generally speaking, as we have the environment variable PATH and the executable files have been put into /usr/bin/, also, we can create soft links for some reason of compatibility, we can execute them anytime and anywhere, why are there some hard links in usr?

Part of output of find /usr -samefile /usr/bin/git:

/usr/libexec/git-core/git-prune
/usr/libexec/git-core/git-diff-index
/usr/libexec/git-core/git-ls-remote
/usr/libexec/git-core/git-merge-recursive
/usr/libexec/git-core/git-push
/usr/libexec/git-core/git-update-index
/usr/libexec/git-core/git-check-mailmap
/usr/libexec/git-core/git-interpret-trailers
/usr/libexec/git-core/git-archive
/usr/libexec/git-core/git-upload-archive
/usr/libexec/git-core/git-rev-parse
/usr/libexec/git-core/git-ls-files
/usr/libexec/git-core/git-am

All of hard links of /usr/bin/git are found in /usr/libexec/git-core/.

Yves
  • 3,291
  • My Ubuntu 16.04 does not have 119 hard links to git. I get just 1 there. ... in fact, the only files which have hard links in my /usr/bin are a bunch of perl commands and python3.5, and that's probably some quirk of Perl and Python installation process. – muru Mar 06 '18 at 03:34
  • 1
    Even assuming 119 hard links, what's wrong with using hard links as long as it's in the same filesystem? Put another way: why should symlinks be used instead of hard links? – muru Mar 06 '18 at 03:40
  • FWIW on Arch I have three hard links to /usr/bin/git, to /usr/bin/git{,-receive-pack,-upload-archive}, and on Debian I have only one. – Sparhawk Mar 06 '18 at 04:30
  • 1
    Can you find which other files are links to it? find /usr -samefile /usr/bin/git should give you a list. The git package doesn't have them itself so I'm curious what does. – Michael Homer Mar 06 '18 at 04:39
  • An 11MB git binary makes it seem like this was installed from source, unstripped... – Stephen Kitt Mar 06 '18 at 05:36
  • @MichaelHomer see my re-edition. – Yves Mar 06 '18 at 05:38

2 Answers2

4

The git links have nothing to do with the PATH, they’re a space-saving measure.

Generally speaking, in most cases for “installed” software, hard links are preferable to symbolic links when possible, because they’re more efficient and resilient. You’ll see quite a few binaries in /usr/bin with hard links, including perl, and that’s fine.

git packages do tend to use symbolic links instead, because of the large number of links involved and the problems that can cause. If you install git from source, it will use hard links by default if at all possible; you can disable that by adding NO_INSTALL_HARDLINKS=1 to the make install command’s arguments.

Stephen Kitt
  • 434,908
  • Oh I see, I did install git from source. This should be why I got so many hard links... I installed git from source because https://askubuntu.com/questions/186847/error-gnutls-handshake-failed-when-connecting-to-https-servers/187199#187199 – Yves Mar 06 '18 at 06:13
3

Often, a single binary with multiple related functions has multiple hard links, in order to let each function have a distinct, memorable command, and still not duplicate any code that all those functions might have in common.

Making the various functions of a single binary appear as distinct commands is also an easy, shell-independent way to make the functions TAB-completable: for example, in bash, if you only remember the first few letters of some command, just type the letters you remember and press TAB twice: you'll get a list of all commands with those initial letters.

Symbolic links can also be used for this, but if all the linked commands are expected to be in the same directory, hard links are the most space-efficient solution: instead of duplicating an entire file, or just using up an extra inode like a symlink might do (on some filesystems), a hard link occupies just a directory entry.

If you want to, you can easily make a script behave like this too:

#!/bin/sh

case "${0##*/}" in
    name1)
        # do something
        ;;
    name2)
        # do something else
        ;;
    *)
        # output an error message, or perhaps usage instructions
        ;;
esac
telcoM
  • 96,466
  • I think that there is no "might" about it. Be confident! (-: Do you actually know of any filesystem formats where a symbolic link does not use an i-node? How do they square that with the necessary semantics of lstat()? – JdeBP Mar 06 '18 at 07:58
  • NFS, XFS and Btrfs are mentioned as examples where a symlink is not stored within an inode, but on closer inspection it seems to mean on those filesystems a symlink consumes an inode plus some other stuff. – telcoM Mar 06 '18 at 08:12