假设您知道目标是符号链接而不是文件,那么使用链接rm
和unlink
删除链接之间有什么区别吗?
答案1
每当您遇到此类问题时,最好做一个小测试,看看实际发生了什么。为此,您可以使用strace
.
取消链接
$ touch file1
$ strace -s 2000 -o unlink.log unlink file1
R M
$ 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。
答案2
POSIX 指定unlink
实用程序只调用 C 库unlink
函数,而不调用其他函数。没有选择。如果您将有效的路径名传递给非目录的内容,并且您对该对象所在的目录具有写权限,则将unlink
删除它。
rm
是一个传统的 Unix 命令,它具有一些其他功能,并且不完全是 的超集unlink
(见下文)。
一是rm
开展安全检查。如果您尝试访问rm
没有写入权限的对象(这与您删除它的能力无关:包含目录的权限是!),rm
除非-f
指定,否则仍然会拒绝。 rm
如果文件不存在,通常会抱怨unlink
;不过有了-f
,rm
就不抱怨了。这经常在 Makefiles ( clean: @rm -f $(OBJS) ...
)中被利用,因此make clean
当没有任何内容可删除时不会失败。
其次,rm
具有-i
交互式确认删除的选项。
第三,rm
递归-r
删除目录,这是unlink
不需要做的事情,因为 C 库函数不这样做。
该unlink
实用程序并不完全是一个精简的rm
.它执行的功能的子集rm
,但它的语义是以下内容的组合rm
和 -f
和 rm没有 -f
。
假设您只想删除一个常规文件,无论其自身的权限是什么。此外,假设您希望命令在文件不存在或任何其他原因时失败。 既不符合要求rm file
,也不rm -f file
符合要求。rm file
如果文件不可写,将拒绝。但rm -f file
如果文件丢失,将忽略投诉。unlink file
做这个工作。
unlink
引入可能是因为rm
它太聪明了:有时你只想要纯粹的 Unixunlink
语义:“如果目录权限允许,请使该目录条目消失”。
答案3
答案4
另外,通过 rm,您可以使用 glob 删除多个文件。通过取消链接,您可以一次删除一个文件。
touch f{1..10}
rm f* # works
touch f{1..10}
unlink f* # doesn't work (expands to unlink f1 f2 ... f10)
unlink f1 # works