X-Git-Url: https://iankelling.org/git/?p=lnf;a=blobdiff_plain;f=lnf;h=b4701dff636fad888363677ddac4d716dfdea61d;hp=c907b6246416e27a6bbb0d5b9fa6cf9d7922c61b;hb=e51702380450ee0b4719a17744208975730ddff7;hpb=fae0c9143e694a3ed895cee68d1adad9bc359f05 diff --git a/lnf b/lnf index c907b62..b4701df 100755 --- a/lnf +++ b/lnf @@ -9,7 +9,8 @@ Usage: lnf TARGET (2nd form) lnf TARGET... DIRECTORY (3rd form) -Remove existing file in the using trash-put or rm -rf if it is not available. +Remove existing file in the using trash-put or rm -rf if it is not available, +or trash-put fails due to a cross-filesystem link. Create directory if needed. Slightly more restrictive arguments than ln. In the 1st form, create a link to TARGET with the name LINK_NAME. In the 2nd @@ -36,32 +37,32 @@ links to each TARGET in DIRECTORY." shopt -s extglob - local remove x - if type -P trash-put >/dev/null; then - remove=trash-put - else - remove="rm -rf" - fi + local x ret prefix dir to_remove + to_remove=() if [[ $nodir ]]; then - if [[ -e "$2" || -L "$2" ]]; then - $remove "$2" - elif ! mkdir -p "$(dirname "$2")"; then - echo "lnf error: failed to make directory $(dirname "$2")" - return 1 + dir="$(dirname "$2")" + if [[ -e $2 || -L $2 ]]; then + to_remove+=("$2") + elif [[ ! -d $dir ]]; then + if [[ -e $dir || -L $dir ]]; then + to_remove+=("$dir") + fi + if ! mkdir -p "$(dirname "$2")"; then + echo "lnf error: failed to make directory $(dirname "$2")" + return 1 + fi fi elif (( $# >= 2 )); then if [[ -d ${!#} ]]; then - local oldcwd=$PWD - cd "${!#}" # last arg + prefix="${!#}/" # last arg for x in "${@:1:$(( $# - 1 ))}"; do # all but last arg - # remove any trailing slashes, uses extglob + # Remove 1 or more trailing slashes, using. x="${x%%+(/)}" - # remove any leading directory components - x="${x##*/}" - [[ -e "$x" || -L "$x" ]] && $remove "$x" + # remove any leading directory components, add prefix + x="$prefix/${x##*/}" + [[ -e "$x" || -L "$x" ]] && to_remove+=("$x") done - cd "$oldcwd" else if ! mkdir -p "${!#}"; then echo "lnf error: failed to make directory ${!#}" @@ -69,7 +70,26 @@ links to each TARGET in DIRECTORY." fi fi elif [[ $# -eq 1 ]]; then - [[ -e "${1##*/}" || -L "${1##*/}" ]] && $remove "${1##*/}" + [[ -e "${1##*/}" || -L "${1##*/}" ]] && to_remove+=("${1##*/}") + fi + if (( ${#to_remove[@]} >= 1 )); then + if type -P trash-put >/dev/null; then + trash-put -- "${to_remove[@]}" || ret=$? + # trash-put will fail to trash a link that goes across filesystems (72), + # and for empty files (74) + # so revert to rm -rf in that case + if [[ $ret == 72 ]]; then + echo "$0: using rm -rf to overcome cross filesystem trash-put limitation" + rm -rf -- "${to_remove[@]}" + elif [[ $ret == 74 ]]; then + echo "$0: using rm -rf to overcome empty file/dir trash-put limitation" + rm -rf -- "${to_remove[@]}" + elif [[ $ret && $ret != 0 ]]; then + return $x + fi + else + rm -rf -- "${to_remove[@]}" + fi fi $reset_extglob && shopt -u extglob