ターゲットがファイルではなくシンボリックリンクであることを知っていると仮定すると、リンクの使用とrm
削除のunlink
間に違いはありますか?
ベストアンサー1
このような問題が発生するたびに、実際に何が起こっているのかを確認するために小さなテストを実行することをお勧めします。このために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()
http://linux.die.net/man/2/unlinkat。
unlinkat() システムコールは、このマニュアルページで説明されている違いを除いて、unlink(2) または rmdir(2) (フラグに AT_REMOVEDIR フラグが含まれているかどうかに依存します) とまったく同じように動作します。
pathnameに指定されたパス名が相対パスである場合は、ファイル記述子dirfdが参照するディレクトリに基づいて解釈されます(unlink(2)とrmdir(2が実行するように、呼び出しプロセスの現在の作業ディレクトリに基づいていない))。相対パス名を表します)。
pathnameに与えられたパス名が相対的でdirfdが特別な値AT_FDCWDの場合、pathnameは呼び出しプロセスの現在の作業ディレクトリに基づいて解釈されます(unlink(2)とrmdir(2)のように)。
pathnameに与えられたパス名が絶対パス名である場合、dirfdは無視されます。