7

I've learnt about aliases and symbolic links ages ago, but only recently learnt of the link command from symbolic link vs. alias

Is the link command in terminal on my MacOS - version is Sonoma 14.4.1 the same as ln or is it its own command?

I've not actually done this often on terminal, but I did:

touch test1.txt

then edited it in a text editor with the content "Test"

and then in terminal:

link test1.txt test2.txt

When would the link command be useful on MacOS as compared to symbolic link and alias?

If you could explain - much appreciated!

4
  • 1
    See this existing (succinct) answer
    – Allan
    Mar 28 at 13:30
  • 1
    @Allan The question here seems to be about the link command.
    – nohillside
    Mar 28 at 14:20
  • I was addressing the question about the differences between them
    – Allan
    Mar 28 at 14:22
  • @allan Your answer provides a lot of valuable details, I don't see how it answers "Is the link command [...] the same as ln". OTOH, my answer below needed an edit as well now that I reread the question :-)
    – nohillside
    Mar 28 at 14:27

3 Answers 3

10

On macOS, both executables have the same inode number, so technically they are the same.

$ ls -il /bin/{link,ln}
1152921500312524105 -rwxr-xr-x  2 root  wheel  101968 Mar 21 07:13 /bin/link*
1152921500312524105 -rwxr-xr-x  2 root  wheel  101968 Mar 21 07:13 /bin/ln*

If you run man link, you get the same man page as for ln. The difference is that link doesn't take any options and always creates a hard link. For the differences between hard links, symbolic links and aliases, see this answer.

SYNOPSIS
     ln [-L | -P | -s [-F]] [-f | -iw] [-hnv] source_file [target_file]
     ln [-L | -P | -s [-F]] [-f | -iw] [-hnv] source_file ... target_dir
     link source_file target_file

...

When the utility is called as link, exactly two arguments must be supplied, neither
of which may specify a directory.  No options may be supplied in this simple mode
of operation, which performs a link(2) operation using the two passed arguments.

Honestly, I don't see a practical use for link nowadays (I didn't even know this variant exists, and I'm using Unix-style systems for >30 years now).

0
3

I think the correct answer here is very historical.

In Unix version 6, the filesystem was not strictly hierarchical. You could actually have multiple names for a directory. This was "eliminated" in version 7 (but not completely). And mkdir and rmdir where suid programs that did multiple syscalls to make or remove the directory.

At this time, link could make a hard link to a directory. With version 7, link required you already be root to hard link a directory. While the ability to hard link a directory has gone away, the command to do it has not. Presumably, the command is retained because there might be people (and scripts) using it.

Since the command passes its parameters straight to the kernel syscall, the behavior can be a little more predictable. Notably, if the target exists, link always fails, while ln will append the original filename without path if the target is a directory.

It should be noted that the strict hierarchical nature of the filesystem is now often part of the filesystem design.

Edit: I'm not actually sure when the link command was added. It doesn't seem to show up in the version 7 electronic man pages I have (and I'm not sure where my print copy is). It was certainly in the VAX-based BSD I used. It is trivial to implement... just a few lines of code.

2
  • I have vague memories of reading that Apple reinstated/reinvented hardlinks to directories for Time Machine backups (so that unchanged directory trees could be efficiently stored)…?
    – gidds
    Mar 29 at 21:18
  • @gidds: possible. The downside of directory hard links is that .. doesn't work right. On the other hand, you can certainly hardlink the files between multiple generations of backups. And even hardlinks are ignored my many people. (Unix is not unusual in having them, only in treating them properly. MSWindows has hard links. VAX/VMS had hard links. and that's just the ones I know of.)
    – David G.
    Mar 30 at 1:47
1

Multiple file names can be hard linked to the same file. Each link can occur in the same directory or different directories. For example, if two difference collections contain the same image and both collections are stored in different directories, then when prudent space can be saved by storing the image in a single file. A file name can then be stored in each directory with a link back to the file's inode. In other words, a filename is stored in each directory along with the inode. The file associated with the inode also has an associated reference counter which would be set to 2. The filenames can be different, but the inode would be the same. Another example would be where a file contains time zone information for a given city. A directory could contain a collection of files named after cities. In this case, a single time zone file could be linked to multiple city names within the same directory.

Executable object files have the ability to determine path and file name given to invoke them. As for the executable with the names ln in link, only the name link has special meaning. I will try to illustrate through the following examples. In the first example, an error message is produced. The message shows the command knows its name is ln.

% ln -z
ln: illegal option -- z
usage: ln [-Ffhinsv] source_file [target_file]
       ln [-Ffhinsv] source_file ... target_dir
       link source_file target_file

In the next example, the command knows its path and name is /bin/ln.

% /bin/ln -z
/bin/ln: illegal option -- z
usage: ln [-Ffhinsv] source_file [target_file]
       ln [-Ffhinsv] source_file ... target_dir
       link source_file target_file

Below, I create a local directory, then copied the command to the directory. Here the command knows its name is now fred.

% cd ~
% mkdir test
% cd test
% cp /bin/ln fred
% ./fred -z
./fred: illegal option -- z
usage: ln [-Ffhinsv] source_file [target_file]
       ln [-Ffhinsv] source_file ... target_dir
       link source_file target_file

This time I successfully create a symbolic link.

% echo hi >hi.txt
% ./fred -s hi.txt hi2.txt
% ls -li
total 72
114259724 -rwxr-xr-x  1 davidanderson  staff  32160 Mar 28 15:16 fred
114261744 -rw-r--r--  1 davidanderson  staff      3 Mar 28 15:18 hi.txt
114261755 lrwxr-xr-x  1 davidanderson  staff      6 Mar 28 15:18 hi2.txt -> hi.txt

However, if the rename the command to link, then I can not create a new symbolic link. The name link has a special meaning.

% mv fred link
% ./link -s hi.txt hi3.txt
./link: illegal option -- s
usage: ln [-Ffhinsv] source_file [target_file]
       ln [-Ffhinsv] source_file ... target_dir
       link source_file target_file

I can however successfully create a hard link. Below both hi.txt and hi3.txt have the same inode and the number of links (i.e. reference count) is set to 2.

% ./link hi.txt hi3.txt
% ls -li
total 80
114261744 -rw-r--r--  2 davidanderson  staff      3 Mar 28 15:18 hi.txt
114261755 lrwxr-xr-x  1 davidanderson  staff      6 Mar 28 15:18 hi2.txt -> hi.txt
114261744 -rw-r--r--  2 davidanderson  staff      3 Mar 28 15:18 hi3.txt
114259724 -rwxr-xr-x  1 davidanderson  staff  32160 Mar 28 15:16 link

Question and answers here at Ask Different are not supposed to get into programming. However, if interested, you can read the pertinent source for the macOS 14.3 version at this link. The main entry point is at line 74. By line 91, the path has been removed and the code is checking to see if the name is link.

3
  • 2
    I wouldn't describe this as unusual. It's the same as how grep, egrep and fgrep are the same binary, or how it's fairly common for bash and sh to be the same executable (albeit one running in a reduced-featureset compatibility mode when started under the sh name). Mar 29 at 19:23
  • @CharlesDuffy: I do not currently have Sonoma 14.4.1 installed to verify if your comment is true for the OP's question. With Catalina 10.15.7, grep, egrep, fgrep, bash and sh have different inodes. With Monterey 12.5, bzegrep, bzgrep, fgrep, zegrep, zgrep, bzfgrep, egrep, grep and zfgrep share the same inode. Again, bash and sh have different inodes. For Ventura 13.3.1 (a), bzegrep, bzgrep, zegrep, bzfgrep, grep and zfgrep share the same inode. Also, fgrep, zgrep and egrepshare the same inode. Again, bash and sh have different inodes. Mar 29 at 23:12
  • Anyway, I basically agree with your comment and have changed my answer accordingly. Mar 29 at 23:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .