128

古いものをリンク解除して新しいものを作成する以外に、シンボリックリンク(シンボリックリンク)によって参照されるパス名を変更するメカニズム(コマンドラインプログラムではなくシステムコール)を提供するオペレーティングシステムはありますか?

POSIX 標準にはありません。Solaris 10 にはありません。MacOS X 10.5 (Leopard) にはありません。(私は、AIX も HP-UX もそうではないことはかなり確信しています。このLinux システム コールのリストから判断すると、Linux にもそのようなシステム コールはありません。)

するものはありますか?

(答えは「いいえ」だと思います。)


否定を証明するのは難しいので、問題を整理しましょう。

古いシンボリックリンクを削除して新しいシンボリックリンクを作成せずに、シンボリックリンクの値 ( によって返される文字列) を書き換えるシステムコールがない (Unix ライクな) 一部の (Unix ライクな) オペレーティングシステムがまだリストされていないことがわかっている場合は、readlink()それを追加してください。答えで。

4

8 に答える 8

167

はい、できます!

$ ln -sfn source_file_or_directory_name softlink_name
于 2012-07-02T16:46:08.123 に答える
112

私の知る限り、いいえ、できません。削除して再作成する必要があります。実際には、シンボリックリンクを上書きして、それが参照するパス名を更新できます:

$ 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

編集:OPがコメントで指摘したように、--forceオプションを使用するとbeforelnへのシステムコールが実行されます。以下、それを証明する私のLinuxボックスでの出力:unlink()symlink()strace

$ strace -o /tmp/output.txt ln -s -f .bash_aliases test
$ grep -C3 ^unlink /tmp/output.txt 
lstat64("test", {st_mode=S_IFLNK|0777, st_size=7, ...}) = 0
stat64(".bash_aliases", {st_mode=S_IFREG|0644, st_size=2043, ...}) = 0
symlink(".bash_aliases", "test")        = -1 EEXIST (File exists)
unlink("test")                          = 0
symlink(".bash_aliases", "test")        = 0
close(0)                                = 0
close(1)                                = 0

したがって、最終的な答えは「いいえ」だと思います。

編集: 以下は、2016 年頃の unix.stackexchange.com での Arto Bendiken の回答からコピーされたものです。

これrename(2)、最初に一時的な名前で新しいシンボリックリンクを作成し、次に古いシンボリックリンクを一度にきれいに上書きすることにより、実際にアトミックに行うことができます。マニュアルページに記載されているように:

newpathがシンボリック リンクを参照する場合、リンクは上書きされます。

シェルでは、mv -T次のようにこれを行います。

$ mkdir a b
$ ln -s a z
$ ln -s b z.new
$ mv -T z.new z

strace最後のコマンドを実行して、実際に内部で使用していることを確認できますrename(2)

$ strace mv -T z.new z
lstat64("z.new", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
lstat64("z", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
rename("z.new", "z")                    = 0

上記の と の両方が Linux 固有であることに注意してmv -Tくださいstrace

FreeBSD では、mv -h交互に使用します。

編集者注:これは、~2.15 以来、Capistrano が何年もの間行ってきた方法です。このプルリクエストを参照してください。

于 2009-09-23T14:59:39.437 に答える
14

古いシンボリックリンクを明示的にリンク解除する必要はありません。あなたはこれを行うことができます:

ln -s newtarget temp
mv temp mylink

(または同等の symlink および rename 呼び出しを使用します)。名前の変更はアトミックであるため、これは明示的にリンクを解除するよりも優れています。したがって、リンクが常に古いターゲットまたは新しいターゲットを指していることを保証できます。ただし、これは元の inode を再利用しません。

一部のファイルシステムでは、シンボリックリンクのターゲットが十分に短い場合、(ブロックリストの代わりに) i ノード自体に格納されます。これは作成時に決定されます。

実際の所有者とグループは重要ではないという主張に関して、 Linux のsymlink(7)は、それが重要な場合があると述べています。

lchown(2) を使用して、既存のシンボリック リンクの所有者とグループを変更できます。シンボリック リンクの所有権が問題になるのは、スティッキー ビットが設定されているディレクトリでリンクが削除または名前変更されている場合のみです (stat(2) を参照)。

シンボリック リンクの最終アクセスと最終変更のタイムスタンプは、utimensat(2) または lutimes(3) を使用して変更できます。

Linux では、シンボリック リンクのアクセス許可はどの操作にも使用されません。パーミッションは常に 0777 (すべてのユーザー カテゴリの読み取り、書き込み、および実行) であり、変更することはできません。

于 2009-09-24T16:35:31.740 に答える
2

上記の正しい答えに対する警告:

-f / --force メソッドを使用すると、ソースとターゲットを混同するとファイルが失われるリスクがあります。

mbucher@server2:~/test$ ls -la
total 11448
drwxr-xr-x  2 mbucher www-data    4096 May 25 15:27 .
drwxr-xr-x 18 mbucher www-data    4096 May 25 15:13 ..
-rw-r--r--  1 mbucher www-data 4109466 May 25 15:26 data.tar.gz
-rw-r--r--  1 mbucher www-data 7582480 May 25 15:27 otherdata.tar.gz
lrwxrwxrwx  1 mbucher www-data      11 May 25 15:26 thesymlink -> data.tar.gz
mbucher@server2:~/test$ 
mbucher@server2:~/test$ ln -s -f thesymlink otherdata.tar.gz 
mbucher@server2:~/test$ 
mbucher@server2:~/test$ ls -la
total 4028
drwxr-xr-x  2 mbucher www-data    4096 May 25 15:28 .
drwxr-xr-x 18 mbucher www-data    4096 May 25 15:13 ..
-rw-r--r--  1 mbucher www-data 4109466 May 25 15:26 data.tar.gz
lrwxrwxrwx  1 mbucher www-data      10 May 25 15:28 otherdata.tar.gz -> thesymlink
lrwxrwxrwx  1 mbucher www-data      11 May 25 15:26 thesymlink -> data.tar.gz

もちろんこれは意図的なものですが、通常は間違いが発生します。したがって、シンボリックリンクを削除して再構築するのは少し手間がかかりますが、少し節約になります:

mbucher@server2:~/test$ rm thesymlink && ln -s thesymlink otherdata.tar.gz 
ln: creating symbolic link `otherdata.tar.gz': File exists

少なくとも私のファイルを保持します。

于 2014-05-25T13:32:47.457 に答える
1

リンクを解除して新しいものを作成しても、最終的には同じことになりますか?

于 2009-09-23T14:59:46.580 に答える
0

念のため、ミッドナイト コマンダー (mc) でシンボリック リンクを編集する方法があります。メニュー コマンドは次のとおりです (私の mc インターフェイスではフランス語で):

Fichier / Éditer le lien symbolique

これは次のように翻訳できます。

File / Edit symbolic link

ショートカットは Cx Cs

内部でln --forceコマンドを使用しているのかもしれませんが、わかりません。

今、私は一度にたくさんのシンボリックリンクを編集する方法を見つけようとしています (それが私がここにたどり着いた方法です)。

于 2014-07-07T18:11:25.660 に答える
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"
}
于 2017-11-26T22:19:03.727 に答える