FreeBSDで、同じハードリンク同士の片方をもう片方にmvしても両方残るのは仕様?

$ touch foo1; ln foo1 foo2 $ mv foo2 foo1 $ ls foo* foo1 foo2 になる件について。
34
切り取り線 @cuthereline

FreeBSDで、同じハードリンク同士の片方をもう片方にmvしても両方残るのは仕様? $ touch foo1; ln foo1 foo2 $ mv foo2 foo1 $ ls foo* foo1 foo2 ←ナゼfoo2が残ってる?? うーむシェルスクリプト複雑になるなぁ…

2013-10-17 04:20:50
SODA Noriyuki @n_soda

@syuu1228 NetBSDだとfoo2は消えますね。Solaris 9だと「mv: foo2 and foo1 are identical」とエラーが出ます(mvの終了コードは2)。エラーも出ないのにfoo2が残るのは、FreeBSD/OS Xのバグじゃないかなあ。

2013-10-17 12:47:39
SODA Noriyuki @n_soda

@syuu1228 POSIX 確認したら、この挙動も許されてるみたい http://t.co/nJSeXtwvSw の 2. の a.。Solaris 9は b.、NetBSD と Linux は c. ですね。

2013-10-17 12:54:08
enami tsugutomo @_enami

@n_soda @syuu1228 ソースみると freebsd はこのケースは意図して NOP にしてますね。 3577 行目あたり。 http://t.co/zvtNpOiama

2013-10-17 13:03:17
イスラエルエリカちゃん @syuu1228

“If the source is the same as the destination, then there is nothing to do.” http://t.co/HfbcvMjQda

2013-10-17 13:04:46
イスラエルエリカちゃん @syuu1228

あれ?これだとerror = -1が返りそうに見えるけどそうならないのかな? http://t.co/jQQ6yZJcTw

2013-10-17 13:05:31
enami tsugutomo @_enami

@syuu1228 そのすぐ先で -1 なら 0 にしてる

2013-10-17 13:06:59
イスラエルエリカちゃん @syuu1228

if (error == -1) return 0ってちょっとすごいな

2013-10-17 13:08:49
SODA Noriyuki @n_soda

@_enami @syuu1228 rename(2)の挙動はNetBSDもSolarisも一緒(この挙動はPOSIXで規定されている)なので、mv(1)側の違いのような。規格上2.a.が許されてる理由って、歴史的理由は別として 何だろうね。その方が便利なことがあるってことかな。

2013-10-17 13:11:06
橙よつ葉🍊🍀 @orange_clover

Windowsだとfoo1だけだな(誰も興味ない https://t.co/YCqiJSpcWy echo.>foo1 mklink /H foo2 foo1 move foo2 foo1 1 個のファイルを移動しました。 dir /b foo* foo1

2013-10-17 13:17:12
enami tsugutomo @_enami

@n_soda @syuu1228 rename(2) の挙動がそもそもそうってことは、何もしないと 2.a になるってことじゃないの?

2013-10-17 13:41:51
SODA Noriyuki @n_soda

@_enami @syuu1228 それかあ。2.b や 2.c は race あるからなあ。

2013-10-17 13:48:49
enami tsugutomo @_enami

@n_soda @syuu1228 ちなみに n だと mv(1) がつかう rename(2) はその posix 仕様じゃなくて posix_rename(2) がその仕様だね

2013-10-17 14:03:09
ふみやす@シェルまおう(自称でない) @satoh_fumiyasu

.@uspmag エラーメッセージもなく、終了コードも 0 になるのでしょうか? それはさすがにバグではないでしょうか。Linux (GNU mv) だと上書きされ、Solaris 10 だと「mv: foo1 と foo2 は同一です。」と言われて終了コード 2 になりました。

2013-10-17 14:16:54
ふみやす@シェルまおう(自称でない) @satoh_fumiyasu

rename(2) は成功 (0を返す) くせに移動元の名前が消えないってこと? > *BSD https://t.co/FGboC5wSl4 https://t.co/gCvAQNIlBf FreeBSD 9 の rename(2) 読んでみたけど、そんなことは書いてない。

2013-10-17 14:22:16
SODA Noriyuki @n_soda

@satoh_fumiyasu rename(2)については、Linuxも挙動としては同じです: http://t.co/BH4q4dgYxv の then rename() does nothing, and returns a success status.のとこです。

2013-10-17 17:56:53
ふみやす@シェルまおう(自称でない) @satoh_fumiyasu

@n_soda ありがとうございます。そちらは未確認でした。Solaris, AIX も同じで、rename(2) に記載ありました。あまり直感的でないですが、これが一般的なようですね…。

2013-10-17 18:02:23
enami tsugutomo @_enami

もともと bsd の rename(2) は from to がまったく同じ (rename("/tmp/a", "/tmp/a") とか)のときだけが NOP だったんだな。NetBSD の場合は今の rename(2) もそうで、__posix_rename(2) だと違うと

2013-10-17 18:32:41
SODA Noriyuki @n_soda

https://t.co/tjx6FUtZhA というわけで、もともとの *BSD の rename(2) の仕様 だと、POSIXの mv(1) の2.cの挙動→FreeBSDはPOSIXに合わせてrename(2)の挙動を変えたので2.aの挙動になったって話みたい。

2013-10-17 19:09:35
SODA Noriyuki @n_soda

NetBSDのrename(2)は伝統的 *BSD のままの仕様だけど、#define _POSIX_C_SOURCEするか、#define _XOPEN_SOURCEすれば、POSIX仕様どおりの動作になると。

2013-10-17 19:11:18
SODA Noriyuki @n_soda

@_enami @syuu1228 どうも。NetBSD上でもrename(2)単体で動かして動作確認したつもりだったけど、どうも確認ミスってたみたい。

2013-10-17 19:12:08
SODA Noriyuki @n_soda

@satoh_fumiyasu POSIX仕様がこうなってますからね>これが一般的。NetBSD使えば、直感的な動作となる模様ですw: https://t.co/hZvOCutenu https://t.co/tjx6FUtZhA https://t.co/TALrF6tyaH

2013-10-17 19:15:13
Daichi GOTO @daichigoto

ハードリンクは滅びん。何度でも蘇るさ “@uspmag: FreeBSDで、同じハードリンク同士の片方をもう片方にmvしても両方残るのは仕様? $ touch foo1; ln foo1 foo2 $ mv foo2 foo1 $ ls foo* foo1 foo2 ←ナゼfo

2013-10-17 21:23:32
1 ・・ 5 次へ