シンボリックリンクを編集するにはどうすればよいですか?


64

シンボリックリンクの私の基本的な理解は、特別なファイル、別のファイルへの文字列パスを含むファイルとしてです。カーネルのVFSはその多くを抽象化しますが、シンボリックリンクを編集できないように見える理由はありますか?

つまり、シンボリックリンクを編集できますか?そうでない場合は、なぜですか?


シンボリックリンクを置き換える方法はいろいろありますが(現在2つの選択肢が回答セクションにあります)、置換がシンボリックリンクを処理する唯一の方法であるように見える理由についての説明を得ることは興味深いでしょう。それらが指す場所を変更できないのはなぜですか?


あなたの理解は少し限られています。それが「ファイル」と呼ばれる唯一の理由は、それに対するより良い言葉がないからです。
シャドゥール

5
Windowsの変形である恥ずかしい残虐行為とは異なり、posixスタイルのシンボリックリンクはファイルシステムレイヤー自体で動作します。ファイルシステムを編集する唯一の方法は、ファイルシステムを直接編集することです。通常、それは価値がありません。
シャドゥール

@Shadur .lnkファイルは実際にはシンボリックリンクではありません(NTFSに Vista以降に適切なシンボリックリンクがあります)。それらは、コマンドを実行するためのショートカットのようなものです。特定のフォルダーに変更する場合でも、特定の引数と特定のCWDでプログラムを起動する場合でも同様です。
JAB

回答:


36

ことを考える-fだけでサイレント交換を行い、あなたがして、原子の交換を行うことができますmv -T(-Tが/loc.../linkがディレクトリである場合でも、それは動作します)

ln -s /location/to/link linkname
# ... 
ln -s /location/to/link2 newlink
mv -T newlink linkname

linkname プロセス全体でアクセス可能です。


7
これでアトミック置換が得られますが、まだ編集ではなく置換を行っています(新しいリンクには新しいiノード番号があります)。
-psusi

2
@psusi私は完全に同意します、いくつかのシナリオでは他の答えよりも技術的にわずかに優れたオプションです。
オリ

リンクを別の宛先にリダイレクトする場合、iノード番号の変更は小さな変更のようです。
AMS

4
これはlinkname、ディレクトリへのシンボリックリンクではないと想定しています。それを避けるには、GNUまたはFreeBSDの場合に-Tオプションを使用します。そのようにすると、リンクの権限が保持されないことに注意してください(重要なシステムでは)。mv-hln -sf
ステファンシャゼル

ディレクトリのシンボリックリンクを変更する別の解決策は、次の-nオプションを使用することですln -sfn DESTINATION_DIRECTORY LINK_NAME。上の続きを読むaskubuntu.com/a/186227/69004
sobi3ch

22

編集によって、それが指すファイルを変更することを意味する場合、はい、できます:

$ 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()

次のスタックオーバーフローの回答から取られた。


9
unlink(); symlink();なので、これを「編集」と見なすことができるかどうかは疑問だと思います。アトミックではないため、リンクが存在しないわずかな時間しかありません。
再生

@ mauro.stettlerはい、あなたは正しいです。しかし、これはあなたの視点に依存すると思います。最終結果のみを考慮に入れた場合、他のことは考慮せずに編集済みとみなすことができます。
NlightNFotis

1
Unix Time Sharing Systemの論文から引用されたセクションでは、ハードリンクについて説明しています。これらは、OPが尋ねたシンボリックリンク(シンボリックリンク)とはまったく異なります。
アンスガーエステルマン

4
testのターゲットはディレクトリではないと想定していることに注意してください。そうしln -s -f .profile testないと.profile、そのディレクトリにシンボリックリンクが作成されます。GNUにlnは、これ-Tを回避するオプションがあります。
ステファンシャゼル

9

シンボリックリンクはアトミックに変更する必要があります。あなたがそれらを書いている途中である場合、彼らは動作しません。シンボリックリンクの内容は非常に小さい(Linuxでは最大4095文字:ファイルへのパスの最大長)ため、カーネルレベルでシンボリックリンクの一部を編集する意味はほとんどありません。したがって、カーネルは、シンボリックリンクを編集するためのインターフェイスを提供せず、新しいリンクを作成するためのインターフェイス、symlinkシステムコール(およびunlinkファイルを削除するための汎用インターフェイス)のみを提供します。

symlinkシステムコールは、唯一の新しいシンボリックリンクを作成し、それが既存のファイルを削除しません。これは迷惑ですが、open(新しいファイルを作成したり、既存のファイルを切り捨てることはできますが、既存のファイルを新しく作成したファイルで置き換えることはできません)やなどのファイルを作成する他のシステムコールと一致しますmkdir

シェルでは、発見したように、シンボリックリンクをlnコマンドでアトミックに置き換えることはできませんが(ln -sf前のファイルをリンク解除してからシンボリックリンクを作成します)、最初に一時的な名前でシンボリックリンクを作成し、その後、所定の位置に移動します。

tmp=$(TMPDIR=$(dirname -- "$link") mktemp)
ln -sf -- "$target" "$tmp"
mv -f "$tmp" "$link"

2
mv -f(などln -sf)は$link、ディレクトリをポイントしている場合、必要な処理を行いません。GNU lnとmvには-Tそれがあります。mv(システムコールの名前を変更)しますいつものiノード変更$linkしばらくln -sfT同じことを再利用するかもしれません(+シンボリックリンクのリンクを解除)。
ステファンシャゼル

0

技術的には、既存のシンボリックリンクを編集するための組み込みコマンドはありません。いくつかの短いコマンドで簡単に実現できます。

以下は、既存のシンボリックリンクを更新するために作成した小さなbash / zsh関数です。

# -----------------------------------------
# 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"
}

申し訳ありませんが、あなたが「答える」ことは、尋ねられた質問にリモートでのみ関連しています。
user2233709

こんにちは@ user2233709-ユーザーの質問「どうすればシンボリックリンクを編集できますか?」は、最初の文で、またソリューションを提供することで明確に回答されました。詳しく説明していただけますか?
-blizzrdof77

2
あなたは本当に質問を読みましたか?シンボリックリンクを置き換えるのではなく、修正することができるかどうかについてです。提案された「ソリューション」は、シンボリックリンクを置き換えるスクリプトです。
user2233709

0

(過去に)行った結果としてリンク名が存在すると仮定します。

 ln -s   /the/path/to/a/file   linkname

次に、シンボリックリンクを変更する3つの方法があります。

  • lnを-f強制的に使用し、ディレクトリに対しても使用します-n(inodeを再利用できます)。

    ln -sfn /some/new/path linkname
    
  • シンボリックリンクを削除して、新しいものを作成します(ディレクトリの場合でも):

    rm linkname; ln -s /some/new/path linkname
    
  • 新しいシンボリックリンクを作成し、それを作成しますmv(ディレクトリも原子的に変更します):

    ln -s  /some/new/path newlinkname
    mv -fT newlinkname linkname             # linkname remains after the command
    
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.