“rm”和“unlink”有什么区别?

IQA*_*eas 79 symlink rm

假设您知道目标是符号链接而不是文件,使用rmunlink删除链接之间有什么区别吗?

slm*_*slm 78

每当您遇到此类问题时,最好先设想一个小测试,看看实际发生了什么。为此,您可以使用strace.

取消链接

$ touch file1
$ strace -s 2000 -o unlink.log unlink file1
Run Code Online (Sandbox Code Playgroud)

R M

$ touch file1
$ strace -s 2000 -o rm.log rm file1
Run Code Online (Sandbox Code Playgroud)

当您查看 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)                           = ?
....
Run Code Online (Sandbox Code Playgroud)

随着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 +++
...
Run Code Online (Sandbox Code Playgroud)

除了本手册页中描述的差异外,系统调用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,则路径名将被解释为相对于调用进程的当前工作目录(如 unlink(2) 和 rmdir(2))。

如果 pathname 中给出的路径名是绝对的,则忽略 dirfd。

  • 阅读这个答案让我很高兴,因为当我经常钓到鱼时,我只是以一种强大而灵活的方式“学会钓鱼”,或者有时我以基本的方式“学会钓鱼”在 SO :-) (12认同)
  • 因为它给出了`AT_FDCWD`,`unlink` 和`unlinkat` 之间实际上没有区别。 (2认同)

Kaz*_*Kaz 46

POSIX 指定该unlink实用程序调用 C 库unlink函数而不是其他任何内容。它没有选择。如果您将有效路径名传递给不是目录的内容,并且您对该对象所在的目录具有写权限,unlink则将删除它。

rm是一个传统的 Unix 命令,它具有一些其他功能,并不是unlink(见下文)的超集。

首先,rm进行安全检查。如果您尝试对rm一个您没有写权限的对象(这与您删除它的能力无关:包含目录的权限是!)rm尽管如此,除非-f指定,否则拒绝。 rm如果文件不存在,通常会抱怨unlink;然而-frm没有抱怨。这在 Makefiles ( clean: @rm -f $(OBJS) ...) 中经常被利用,因此make clean在没有要删除的内容时不会失败。

其次,rm具有-i交互确认删除的选项。

第三,rm-r递归删除目录,这是unlink不需要做的事情,因为 C 库函数不这样做。

unlink实用程序并不完全是精简的rm. 它执行功能的一个子集rm,但它的语义是rm with -f和 rm without 的组合-f

假设您只想删除一个常规文件,而不管其自身的权限是什么。此外,假设您希望命令在文件不存在或任何其他原因时失败。 既不符合要求,rm file也不rm -f file符合要求。rm file如果文件不可写,将拒绝。但rm -f file如果文件丢失,将忽略抱怨。unlink file做这项工作。

unlink可能是因为rm太聪明而引入的:有时您只想要纯 Unixunlink语义:“如果目录权限允许,请使此目录条目消失”

  • 这是这里最明确的答案。它实际上给出了“unlink”的*用例*,而不仅仅是描述差异。 (7认同)

cuo*_*glm 24

对于单个文件,rmunlink执行相同的任务,删除文件。正如 POSIX 定义的那样,rm并且unlink都调用unlink()系统调用。

在 GNU 中rm,它调用unlinkat()系统调用,这与unlink()or rmdir()函数等效,除非 path 指定了相对路径。

笔记

在某些系统上,unlink还可以删除目录。至少在 GNU 系统中,unlink永远不能删除一个目录的名字。