シンボリックリンクについての私の基本的な理解は、特別なファイル、別のファイルへの文字列パスを含むファイルとしてです。カーネルのVFSはその多くを抽象化していますが、シンボリックリンクを編集できないように見える理由はありますか?
つまり、シンボリックリンクを編集できますか?そうでない場合、なぜそうではないのですか?
置換シンボリックリンクにはさまざまな方法があることを理解しています(現在、2つの選択肢が回答セクションにあります)。 。なぜあなたは彼らが指す場所を変えることができないのですか?
-f
がサイレント置換を行うだけの場合、 mv -T
でアトミック置換を実行できます(-Tを指定すると、/ loc .../linkがディレクトリであっても機能します) =:
ln -s /location/to/link linkname
# ...
ln -s /location/to/link2 newlink
mv -T newlink linkname
linkname
はプロセス全体を通じてアクセスできます。
編集する場合は、それが指すファイルを変更することを意味し、そうすることができます。
_$ ln -s .bashrc test
$ ls -al test
lrwxrwxrwx 1 Pascal pascal 7 2009-09-23 17:12 test -> .bashrc
$ ln -s .profile test
ln: creating symbolic link `test': File exists
$ ln -s -f .profile test
$ ls -al test
lrwxrwxrwx 1 Pascal pascal 8 2009-09-23 17:12 test -> .profile
_
_-f
_パラメータ(_--force
_)をlnに渡すと、unlink()
システムコールがsymlink()
の直前に呼び出されます。
以下から取得 スタックオーバーフローの回答 。
シンボリックリンクはアトミックに変更する必要があります。あなたがそれらを書いている途中である場合、それらは動作しません。シンボリックリンクの内容は非常に小さい(Linuxでは最大4095文字:ファイルへのパスの最大長)ので、カーネルレベルでシンボリックリンクの一部を編集しても意味がありません。したがって、カーネルはシンボリックリンクを編集するためのインターフェイスを提供せず、新しい変数を作成するためのインターフェイス、symlink
システムコール(およびファイルを削除するための汎用インターフェイスunlink
)のみを提供します。
symlink
システムコールは、新しいシンボリックリンクを作成するだけで、既存のファイルは削除しません。これは厄介ですが、open
(新しいファイルを作成するか、既存のファイルを切り捨てることはできますが、既存のファイルを新しく作成されたファイルで置き換えることはできません)やmkdir
などのファイルを作成する他のシステムコールと一貫しています。
シェルでは あなたが発見した のように、シンボリックリンクをln
コマンド(ln -sf
は、前のファイルのリンクを解除してからシンボリックリンクを作成します)。最初に一時的な名前でシンボリックリンクを作成してから、所定の場所に移動します。
tmp=$(TMPDIR=$(dirname -- "$link") mktemp)
ln -sf -- "$target" "$tmp"
mv -f "$tmp" "$link"
技術的には、既存のシンボリックリンクを編集するための組み込みコマンドはありません。これは、いくつかの短いコマンドで簡単に実現できます。
ここに少しありますbash/zsh function既存のシンボリックリンクを更新するために書きました:
# -----------------------------------------
# Edit an existing symbolic link
#
# @1 = Name of symbolic link to edit
# @2 = Full destination path to update existing symlink with
# -----------------------------------------
function edit-symlink () {
if [ -z "$1" ]; then
echo "Name of symbolic link you would like to edit:"
read LINK
else
LINK="$1"
fi
LINKTMP="$LINK-tmp"
if [ -z "$2" ]; then
echo "Full destination path to update existing symlink with:"
read DEST
else
DEST="$2"
fi
ln -s $DEST $LINKTMP
rm $LINK
mv $LINKTMP $LINK
printf "Updated $LINK to point to new destination -> $DEST"
}
リンク名が(過去に)実行した結果として存在すると仮定します。
ln -s /the/path/to/a/file linkname
次に、シンボリックリンクを変更する3つの方法があります。
Lnを-f
forceで使用し、ディレクトリ-n
でも使用します(inodeは再利用できます):
ln -sfn /some/new/path linkname
シンボリックリンクを削除して、新しいものを作成します(ディレクトリの場合でも)。
rm linkname; ln -s /some/new/path linkname
新しいシンボリックリンクを作成し、次にmv
it(ディレクトリの場合でもアトミック変更):
ln -s /some/new/path newlinkname
mv -fT newlinkname linkname # linkname remains after the command