1#!/usr/bin/env bash
2
3# Try to hardlink a file into a directory, fallback to copy on failure.
4#
5# Hardlink-or-copy the source file in the first argument into the
6# destination directory in the second argument, using the basename in
7# the third argument as basename for the destination file. If the third
8# argument is missing, use the basename of the source file as basename
9# for the destination file.
10#
11# In either case, remove the destination prior to doing the
12# hardlink-or-copy.
13#
14# Note that this is NOT an atomic operation.
15
16set -e
17
18main() {
19    local src_file="${1}"
20    local dst_dir="${2}"
21    local dst_file="${3}"
22
23    if [ -n "${dst_file}" ]; then
24        dst_file="${dst_dir}/${dst_file}"
25    else
26        dst_file="${dst_dir}/${src_file##*/}"
27    fi
28
29    mkdir -p "${dst_dir}"
30    rm -f "${dst_file}"
31    ln -f "${src_file}" "${dst_file}" 2>/dev/null \
32    || cp -f "${src_file}" "${dst_file}"
33}
34
35main "${@}"
36