“rm”和“取消链接”有什么区别?

“rm”和“取消链接”有什么区别?

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

答案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;不过有了-frm就不抱怨了。这经常在 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

使用单个文件,R M取消链接执行相同的任务,删除文件。按照 POSIX 的定义,rm两者unlink都调用取消链接()系统调用。

在 GNU 中rm,它调用取消链接()系统调用,相当于unlink()orrmdir()函数,但路径指定相对路径的情况除外。

笔记

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

答案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

相关内容