“realpath”和“readlink -f”有什么区别

Fel*_*eão 98 shell command

我已经阅读了很多关于realpath命令以及它是如何readlink -f被现在推荐的弃用的。我也在一些地方看到,之所以引入 realpath 是因为 readlink 中缺少这样的功能,而且一旦引入,就不再需要 realpath 并且大多数操作系统供应商都停止了对它的支持。

我提出问题的原因是,我也看到很多人将 推荐readlink -f为“非常相似”的命令realpath,这就是困扰我的原因,因为没有人详细说明“非常相似”的部分。实际差异是什么?

Gil*_*il' 97

realpath周围有几个命令。

realpath实用程序是围绕着一个包装realpath库函数,并已改造很多

Debian的用于维持realpath包(分离dwww木本尚未除自2001年以来就包装和文档改变),但现在已经逐步淘汰。该实用程序已被弃用,因为现在有更多标准替代品(GNUreadlink和很快的 GNU realpath),但当时,GNU 实用程序甚至根本没有readlink。此实现realpath支持一些options以防止符号链接解析或产生以空字符结尾的输出。 BusyBox还包括它自己的realpath命令(它没有选项)。

GNU coreutils于 2012 年 1 月realpath8.15 版中引入了一个命令。这是 BusyBox 和 Debian 的兼容替代品realpath,并且还有许多与 GNU 相同的选项readlink

realpathreadlink -f与 GNU具有相同的效果readlink。这两个命令(或者更确切地说是realpath来自的各种命令readlink -f)的区别在于它们支持的额外选项。

GNUrealpath没有被弃用;它有相反的问题:它太新了,无法在任何地方使用。Debian 过去常常从其软件包中省略 GNUrealpathcoreutils并坚持使用自己的realpath. 我不知道为什么,因为 GNUrealpath应该是一个替代品。但是,从 Debian jessie 和 Ubuntu 16.04 开始,realpath使用的是GNU 。

目前,在 Linux 系统上,规范化可能包含符号链接的路径的最佳选择是readlink -f.

BSD 系统有一个readlink命令,其功能与 GNU 不同readlink。特别是,BSDreadlink没有规范化路径的选项,它只遍历传递给它的符号链接。

readlink,顺便说一句,有同样的问题——它也被发明了很多次(当符号链接被添加到 Unix 时没有添加这个实用程序是一个令人遗憾的遗漏)。它现在已经在具有许多不兼容标志的几个实现中稳定下来(特别是 BSD 与 GNU)。

  • `readlink -f` 早在 GNU 之前就已经在 OpenBSD 中了。所有的 NetBSD、FreeBSD 和 OpenBSD 现在都有 `readlink -f`(你的 [link](http://www.freebsd.org/cgi/man.cgi?query=readlink&sektion=1) 甚至提到了它)。`realpath` 已经在 FreeBSD 和 IRIX 中使用了很长时间(不知道它是否早于 Debian 中的那个)。HPUX 和 IRIX 也有 `readlink`,但没有 `-f`。Debian 实验中的 `realpath` 包现在是来自 coreutils 的包(作为一个实验,看看它是否会破坏一些东西)。dwww `realpath` 更像 `readlink -e` 而 GNU 更像 `readlink -f` 所以它不是一个完整的 dropin 替换 (8认同)
  • `realpath` 自 2002 年以来一直在 FreeBSD 中。在此之前,`pwd` 正在这样做(自 2000 年以来,`pwd some-file` 会在 `file` 上调用 `realpath()`)。Debian 自 1996 年起就有了一个 `realpath` 包。IRIX 上的那个包可能早于它,尽管我没有发现除了 1998 年的 IRIX 6.5 之外的证据。OpenBSD 添加了一个 `-f` 到 `readlink` [在 1997 年](http ://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/readlink/readlink.c?rev=1.10)。[GNU 在 2003 年添加了 `readlink`](https://lists.gnu.org/archive/html/bug-gnu-utils/2003-02/msg00008.html) 并且它从一开始就有 `-f`。 (3认同)
  • 很好的总结谢谢。请注意,要求 debian 切换到 GNU 变体的一个更好的错误是 http://bugs.debian.org/730779 即使现有的 realpath 维护者也希望切换发生 (2认同)

Jam*_*oon 29

tl;dr readlink -f将返回0现有目录中不存在的文件,而realpath返回1. 但是,readlink -e将表现得像realpath并返回1一个不存在的文件(见最后的编辑注释)。

readlink -f

$ readlink -f non-existent-file
/home/user/non-existent-file
$ echo $?
0
Run Code Online (Sandbox Code Playgroud)

readlink -e

$ readlink -e non-existent-file
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)

realpath

$ realpath non-existent-file
non-existent-file: No such file or directory
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)

readlink -f 目录不存在

readlink -f 行为因路径的哪一部分不存在而异。

$ readlink -f /tmp/non-existent-dir/foo
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)

realpath 目录不存在

$ realpath /tmp/non-existent-dir/foo
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)

可用性

readlink已经安装在大多数 Linux 发行版中。然而,realpath也变得更加频繁已经安装了realpath已经被整合进GNU Coreutils的(前几年,这是它自己的独立的包)。

总之

如果要替换调用,realpath ...则使用readlink -e ....
然而,realpath它的分布正变得越来越广泛,因此期望realpath被安装并不是没有道理的。

MMV 的 readlink实现差异很大。默认 Linux 安装中的
MMV realpath可用性变化比readlink.


在 Ubuntu 16 上使用readlink (GNU coreutils) 8.21realpath 版本 1.19进行测试。


编者注

  • 我赞成这个答案,但我建议澄清这指的是 Debian 版本的“realpath”。`realpath` 的 GNU 版本的行为与 `readlink -f` 相同。 (4认同)
  • 可以确认这在 MacOS High Sierra 上不起作用。 (3认同)