Bash: Create hardlink if destination is inside same volume, copy if not

1k views Asked by At

My bash script makes copies of some files to some multiple directories.

In order to save space and maximize speed, I would prefer to make hardlinks instead of copies, since all copies need to remain identical during their life anyway.

The script is ran in different computers, though, and there may be the case where the destination directory exists in a different volume to the origin's. In such a case, I cannot make a hardlink and need to just copy the file.

How do I check if origin and destination directory exist in the same volume, so that I either hard link or copy depending on it?

2

There are 2 answers

2
thiton On

The easy way, by checking whether ln fails where cp succeeds:

ln $SRC $TARGET || cp $SRC $TARGET
1
BRPocock On

A simple way to do so, is just to try both:

    ln "$FROM" "$TO" || cp "$FROM" "$TO"

Depending upon your purposes, creating a reference copy (which is almost as lightweight as an hardlinked file, but allows the two copies to be edited/diverge in future) might work:

    cp --reflink=auto "$FROM" "$TO"

But, you can obtain the device filesystem's device ID using stat:

    if [ $(stat -c %D "$FROM") = $(stat -c %D "$TARGET_DIR") ]; then
          ln "$FROM" "$TARGET_DIR"/
    else
          cp "$FROM" "$TARGET_DIR"/
    fi