「rm」と「unlink」の違いは何ですか?


55

ターゲットがファイルではなくシンボリックリンクであることを知っていると仮定すると、リンクの使用rmunlink削除に違いはありますか?


3
これはかなりよくServerFaultの上で覆われている:serverfault.com/questions/38816/...
SLM

@ slm♦回答はその質問に対応していますが、この質問は異なります。「ターゲットはファイルではなくシンボリックリンクであると知っていると仮定して」
ステファンゴーリチョン

ここで@IQAndreasの回答を受け入れたようには見えません。彼らがあなたを助けたならそうしてください。
グレー

回答:


56

この種の質問があるときはいつでも、実際に何が起こっているのかを確認するための小さなテストを考えるのが最善です。このために使用できますstrace

リンク解除

$ touch file1
$ strace -s 2000 -o unlink.log unlink file1

rm

$ touch file1
$ strace -s 2000 -o rm.log rm file1

結果の2つのログファイルを見ると、各呼び出しが実際に行っていることを「見る」ことができます。

壊す

unlinkそれが呼び出すだunlink()システムコールを:

....
mmap(NULL, 106070960, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6d025cc000
close(3)                                = 0
unlink("file1")                         = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
....

rmそれはわずかに異なるパスです。

....
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid()                               = 1000
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "file1", W_OK)      = 0
unlinkat(AT_FDCWD, "file1", 0)          = 0
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
...

システムコールunlink()とはunlinkat():基本的に、このmanページで説明している違いがある以外は同じですhttp://linux.die.net/man/2/unlinkat

抜粋

unlinkat()システムコールは、このマニュアルページで説明されている違いを除いて、unlink(2)またはrmdir(2)(flagsにAT_REMOVEDIRフラグが含まれているかどうかによって異なります)とまったく同じように動作します。

pathnameで指定されたパス名が相対である場合、(unlink(2)およびrmdir(2 )相対パス名の場合)。

pathnameで指定されたパス名が相対であり、dirfdが特別な値AT_FDCWDである場合、pathnameは呼び出しプロセスの現在の作業ディレクトリ(unlink(2)やrmdir(2)など)を基準にして解釈されます。

pathnameで指定されたパス名が絶対パスの場合、dirfdは無視されます。


1
与えているのでAT_FDCWD、実質的にとの間に違いはunlinkありませんunlinkat
バーマー14

6
それは:-) SO上の基本的な方法で、私は「魚に学んだ」ので、多くの場合、私は魚を取得するときに強力で柔軟な方法で、この回答を読んだり、時々私は、「魚に学ぶ」ことが私を幸せにする
セージ

22

POSIXは、unlinkユーティリティがCライブラリunlink関数を呼び出すことを指定します。オプションはありません。ディレクトリではないものに有効なパス名を渡し、そのオブジェクトが存在するディレクトリへの書き込み権限がある場合、それunlinkを削除します。

rmは、他の機能を少し備えた従来のUnixコマンドであり、完全なスーパーセットではありませんunlink(以下を参照)。

まず、rm安全性チェックを実行します。あなたがしようとした場合rm(!それを削除するあなたの能力には無関係である:直接権限がある)あなたが書き込み権限を持っていない先のオブジェクトrmがない限り、それにもかかわらず拒否する-f指定されています。 rm通常、ファイルが存在しない場合は文句を言いますunlink; しかし、で-frm文句を言いません。これはMakefile(clean: @rm -f $(OBJS) ...)で悪用されることが多いためmake clean、削除するものがない場合に失敗することはありません。

第二に、削除をインタラクティブに確認するオプションrmがあり-iます。

第三に、rm持っている-r再帰的なものであるディレクトリ、除去のためのunlinkCライブラリ関数は、それをしないことから、やるする必要はありませんが。

このunlinkユーティリティは、完全に削除されたものではありませんrm実行することのサブセットを実行しますが、withとrm withoutのrm組み合わせであるセマンティクスを持ちます。rm -f -f

独自のアクセス許可に関係なく、通常のファイルを削除するだけだとします。さらに、ファイルが存在しない場合、またはその他の理由でコマンドを失敗させたいとします。 どちらrm filerm -f file要件を満たしていません。rm fileファイルが書き込み可能でない場合は拒否します。しかしrm -f file、ファイルが欠落している場合に文句を言うのを怠ります。unlink file仕事をします。

unlinkので、おそらく導入されたrm、時にはあなただけの純粋なUnixの希望:あまりにも巧妙であるunlinkセマンティクスを:「ディレクトリのパーミッションが許可した場合、このディレクトリエントリが離れて行くにしてください」


2
これが最も明確な答えです。実際には、単に違いを説明するのではなく、ユースケースを提供しますunlink
ワイルドカード

19

単一のファイルで、rmunlinkは同じタスクを実行し、ファイルを削除します。POSIXが定義されているようにrmunlink両方ともunlink()システムコールを呼び出します。

GNU rmでは、unlinkat()システムコールを呼び出します。これは、pathが相対パスを指定する場合を除き、unlink()またはrmdir()関数と同等です。

注意

一部のシステムでunlinkは、ディレクトリも削除できます。少なくともGNUシステムでunlinkは、ディレクトリの名前を削除することはできません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.