현재 디렉터리의 심볼릭 링크 위치를 다른(상대) 디렉터리의 대상 파일로 바꾸는 스크립트를 만들려고 합니다. 안타깝게도 로컬이 아닌 디렉토리에서 링크를 만드는 방법을 모르고 "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"