ターゲットとシンボリックリンクを交換するヘルプスクリプト

ターゲットとシンボリックリンクを交換するヘルプスクリプト

現在のディレクトリのシンボリックリンクの場所を別の(相対)ディレクトリのターゲットファイルに置き換えるスクリプトを作成しようとしています。残念ながら、ローカルではないディレクトリからリンクを作成する方法がわからず、 "ln -s"に関する情報を検索すると、単純な大文字と小文字の使用のみが検索されます。スクリプト内の他のディレクトリに「cd」できることを知っていますが、より「エレガントな」方法があるはずです。

これは私が持っているものです。

#!/bin/bash
#
# Script to help organize repositories.
# Finds local links and swaps them with their target.
#
# Expects 1 arguments

if [ "$#" -ne 1 ];
then
    echo "Error in $0:  Need 1 arguments: <SYMBOLICLINK>";
    exit 1;
fi



LINK="$1";
LINKBASE="$(basename "$LINK")";
LINKDIR="$(dirname "$LINK")";
LINKBASEBKUP="$LINK-bkup";

TARGET="$(readlink "$LINK")";
TARGETBASE="$(basename "$TARGET")";
TARGETDIR="$(dirname "$TARGET")";

echo "Link:   $LINK";
echo "Target: $TARGET";

#Test for broken link
# test if symlink is broken (by seeing if it links to an existing file)
if [ -h "$LINK" -a ! -e "$LINK"  ] ; then
    echo "Symlink $LINK is broken.";
    echo "Exiting\n";
    exit 1;
fi


mv -f "$TARGET" "/tmp/.";
#   printf "$TARGET copied to /tmp/\n" || exit 1;
mv -f "$LINK" "/tmp/$LINKBASEBKUP";# &&
#   printf "$LINKBASE copied to /tmp/$LINKBASEBKUP\n"; # ||

#   { printf "Exiting"; exit 1; }
# and alternative way to check errors
# [ $? -neq 0 ] && printf "Copy $LINK to $REFDIRNEW failed\nExiting"

mv "/tmp/$TARGETBASE" "$LINK";  #what was a link is now a file (target)
ln -s "$LINK" "$TARGET"; #link is target and target is link

if [ $? -eq 0 ];
then
    echo "Success!";
    exit 0
else
    echo "Couldn't make link to new target. Restoring link and target and exiting";
    mv "/tmp/$LINKBASEBKUP" "$LINK";
    mv "/tmp/$TARGETBASE" "$TARGET";
    exit 1;
fi

どんな助けでも大変感謝します。

ベストアンサー1

GNU ツールを使用すると仮定すると、リンクとターゲットの絶対パスを決定するか、ln -rオプションrealpathを使用して--relative-to相対リンクターゲットを作成できます。

以下は、完全性チェックやクリーンリンクバックアップがない最小の例です。

#!/bin/bash

link=$(realpath -s "$1")  # absolute path to link
target=$(realpath "$1")   # absolute path to target

mv -vf "$link"{,.bak}     # create link backup
mv -vf "$target" "$link"  # move target

# a) use ln -r
ln -vsr "$link" "$target"

# b) or determine the relative path
#target_dir=$(dirname "$target")
#relpath=$(realpath --relative-to="$target_dir" "$link")
#ln -vs "$relpath" "$target"

おすすめ記事