busyboxのディレクトリへのシンボリックリンクをアトミックに変更するにはどうすればよいですか?


18

シンボリックリンクを(可能な限り近くで)アトミックに変更しようとしています。私はもう試した:

ln -sf other_dir existing_symlink

existing_symlinkが指すディレクトリに新しいシンボリックリンクを置くだけです。

ln -sf other_dir new_symlink
mv -f new_symlink existing_symlink

それは同じことをしました:シンボリックリンクをディレクトリに移動しました。

cp -s other_dir existing_symlink

ディレクトリであるため拒否します。

私はそれmv -Tがこのために作られたと読んだことがありますが、busyboxには-Tフラグがありません。

回答:


1

アトミック操作を取得する方法がわかりません。のmanページにsymlink(2)EEXIST、ターゲットが既に存在するかどうかが記載されています。カーネルがアトミック操作をサポートしていない場合、ユーザーランドの制限は無関係です。

またmv -T、たとえあなたがそれを持っているとしても、どのように役立つかわかりません。GNU mvを備えた通常のLinuxボックスで試してください。

$ mkdir a b
$ ln -s a z
$ mv -T b z
mv: cannot overwrite non-directory `z' with directory `b'

私はあなたが2つのステップでこれをしなければならないだろうと思う:古いシンボリックリンクを削除し、それを再作成する。


1
実際、残念ながら、シンボリックをアトミックに変更する方法はありません。最善の方法は、古いリンクを削除して新しいリンクを作成することです。GNU coreutilsには、単一のコマンド(ln -snf)でこれを行うオプションがありますが、内部にはまだ2つのシステムコールがあります。
ジル「SO-停止されて悪」

43

これ実際にを使用してアトミックに実行できます。rename(2)最初に一時的な名前で新しいシンボリックリンクを作成し、次に古いシンボリックリンクを一度にきれいに上書きします。同様にmanページの状態:

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

上記では、両方mv -Tstrace Linux固有です。

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


1
非常に素晴らしい!最後にzからbへのリンクがあると言っておくと役立つかもしれません!
ヴィンチェンツォピイ

OSに依存しないソリューションではrenamemv -hまたはの代わりに直接syscall を使用できるスクリプト言語を使用しますmv -T。Perlの例:perl -e 'rename "z.new", "z" or die $!'
Slaven Rezic

8

ここでArtoが中断したところを取り上げると、これは完全に可能mv -Tですmv

mkdir -p tmp/real_dir1 tmp/real_dir2
touch tmp/real_dir1/a tmp/real_dir2/a
# start with ./target_dir pointing to tmp/real_dir1
ln -s tmp/real_dir1 target_dir
# create a symlink named target_dir in tmp, pointing to real_dir2
ln -sf tmp/real_dir2 tmp/target_dir
# atomically mv it into ./ replacing ./target_dir
mv tmp/target_dir ./

http://axialcorps.wordpress.com/2013/07/03/atomically-replacing-files-and-directories/)を介したコード例


3

試しましたln -snfか?

このオプション-nは、宛先がディレクトリへのシンボリックリンクである場合、宛先の下に書き込むのではなく、宛先を上書きします。

乾杯


3
ln -snfアトミックではありません。宛先のリンクを解除し、目的のシンボリックリンクを作成します。
ジル「SO-悪であるのをやめる」

2
OPがシンボリックリンクのアトミックな変更に「possib [e]に近づく」ことに関心があることを考えると、これは完全に合理的な答えです。アトミックに近づく(またはアトミックになる)より良いものがあれば、それを受け入れることができます。投票する必要はないと思います。
ウィルコ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.