Skip to main content
added 241 characters in body
Source Link
terdon
  • 252.2k
  • 69
  • 480
  • 718

In fact, as the OP found out, at least on Debian systems, cp --preserve=links is sufficient to convert symlinks to hard links if the target directory is the same.


In fact, as the OP found out, at least on Debian systems, cp --preserve=links is sufficient to convert symlinks to hard links if the target directory is the same.

deleted 9 characters in body
Source Link
terdon
  • 252.2k
  • 69
  • 480
  • 718
    $ ls -li c | cc2ter 
    total 0
    17044704 -rw-r--r-- 2 terdon terdon 0 Oct  9 02:50 a
    17044704 -rw-r--r-- 2 terdon terdon 0 Oct  9 02:50 b
    $ ls -li c | cc2ter 
    total 0
    17044704 -rw-r--r-- 2 terdon terdon 0 Oct  9 02:50 a
    17044704 -rw-r--r-- 2 terdon terdon 0 Oct  9 02:50 b
    $ ls -li c 
    total 0
    17044704 -rw-r--r-- 2 terdon terdon 0 Oct  9 02:50 a
    17044704 -rw-r--r-- 2 terdon terdon 0 Oct  9 02:50 b
Source Link
terdon
  • 252.2k
  • 69
  • 480
  • 718

The example in the info page shows you how though the example is a bit hard to follow:

$ mkdir c; : > a; ln -s a b; cp -aH a b c; ls -i1 c
74161745 a
74161745 b

Let's break that down into its component commands:

  • mkdir c; : creates the directory c/

  • : > a; : just a quick way of creating an empty file. It is equivalent to echo "" > a. : is a bash built in which does nothing, see help :.

  • ln -s a b : create a softlink to a called b. At this point, these are the contents of the current directory:

      $ ls -l | cc2ter 
      total 4
      -rw-r--r-- 1 terdon terdon    0 Oct  9 02:50 a
      lrwxrwxrwx 1 terdon terdon    1 Oct  9 02:50 b -> a
      drwxr-xr-x 2 terdon terdon 4096 Oct  9 02:50 c
    

Note that b is a symbolic link (soft link) it does not point to the same inode as a:

    $ ls -i1c a b
    16647344 a
    16647362 b
  • cp -aH a b c; : copy files a and b into directory c. This is where the conversion is happening, the options passed to cp are:

      -a, --archive
            same as -dR --preserve=all
      -d    same as --no-dereference --preserve=links
      -H    follow command-line symbolic links in SOURCE
    

The -H is necessary because (from info cp):

When copying from a symbolic link, `cp' normally follows the link only when not copying recursively.

Since -a activates recursive copying (-R), -H is needed to follow symbolic links. -H means that links are followed despite recursion and will result in hard links being made in the target directory. These are the contents of c/ after the last step (the first column is the inode number):

    $ ls -li c | cc2ter 
    total 0
    17044704 -rw-r--r-- 2 terdon terdon 0 Oct  9 02:50 a
    17044704 -rw-r--r-- 2 terdon terdon 0 Oct  9 02:50 b

Now as to how exactly it works, as far as I can figure out from playing around with it, cp --preserve=links combined with -L or -H will convert symbolic links to hard links if both the link and the target are being copied to the same directory.