`~/Documents` 是相对路径还是绝对路径?

Whi*_*olf 37 shell filenames

这只是一个词汇问题,但它一直在我的脑海中盘旋。

它来自LPIC准备书中的练习考试。根据这本书的正确答案是这~/Documents是一个相对目录,因为它是相对于主目录的。

然而,这本书包含的错别字和错误比例很高,所以我不能认为那里写的所有东西都是理所当然的。在这里我不同意,因为对我来说,~它充当了由 shell 扩展为变量内容$HOME或当前用户主目录路径(参见man bash)的变量,因此实际路径/home/myuser/Documents确实是绝对目录。

甚至Wikipedia一次,在这个话题上对我来说似乎也没有帮助(即使它似乎证实这本书在这个问题上是错误的):

无论当前工作目录如何,绝对路径或完整路径都指向文件系统中的相同位置。为此,它必须包含根目录。

相比之下,相对路径从某个给定的工作目录开始,无需提供完整的绝对路径。

在这里,我再次不同意:根据这个定义,/opt/kde3/bin/../lib不依赖于当前工作目录的路径应该是绝对路径,但是我目前对此的理解与本书作者将这条路径设为相对路径相符。

根据韦伯斯特词典,快速的网络搜索只会增加我的挫败感:

绝对路径- 相对于根目录的路径。它的第一个字符必须是路径名分隔符。

那么$HOME/Documents,甚至$HOME不会被视为绝对目录?或者这个定义是否意味着变量扩展?贝壳的~性格呢?我可以在某处找到相对目录与绝对目录的任何可靠定义,并且我一直都错了吗?

Kev*_*eid 48

这本质上是一个关于术语定义的问题。因此,就您的目的而言,答案是 LPIC 想要的任何东西。但是我们可以根据技术事实得出一些结论:

如果你传递'~/Documents'给一个系统调用,它会~在当前目录中寻找一个完全命名的目录(并且可能会失败)。所以,根据内核使用的路径名的概念,这是一个相对路径——但这不是我们的意思。

~是由外壳程序(以及为方便起见模仿它的其他程序)实现的语法,它将其扩展为真正的路径名。为了说明,~/Documents$HOME/Documents(再次,shell 语法)大致相同。既然$HOME应该是绝对路径,那么的值 $HOME/Documents也是绝对路径。但是文本$HOME/Documents还是~/Documents要被shell 展开才能成为我们所说的路径。

因此,如果我想精确和一致,我会说这~/Documents扩展为绝对路径的 shell-script 片段。

  • 你可以随心所欲地发现它是可疑的,但它是 [documented](http://www.gnu.org/software/bash/manual/bash.html#Tilde-Expansion) 并且应该很容易在 C 中确认或反驳。 (6认同)
  • 其他程序模仿shell 实现了`~` 语法,因为它是一个有用的快捷方式。我实际上不知道是否有一个库函数可以进行扩展,但这绝对是与实际使用路径名分开完成的事情。 (6认同)
  • `glob` 和 `wordexp` 进行波浪号扩展等。 (2认同)
  • @MichaelKjörling:一些程序实现了`~` 扩展;大多数没有。例如,如果你输入 `ls -l ~`,`ls` 程序永远不会看到 `~` 字符;它在调用 `ls` 之前被 shell 展开。如果你真的把 `~` 传递给 `ls`,它不会特别对待它;试试 `ls -l '~`'`(它会尝试列出一个名为 `~` 的文件)。 (2认同)

Pet*_*des 42

如果作者试图通过将文字字符串(没有外壳扩展)作为路径来抓住你,那么它就是一个相对路径 ( mkdir -p './~/Documents')。除此以外:


这是一个绝对路径,因为解析它不依赖于进程的当前工作目录。 相对路径总是意味着相对于进程的工作目录。或者在符号链接目标的情况下,相对于符号链接的位置。(gcc -> gcc-5.2对比gcc -> /usr/bin/gcc-5.2)。这对于 NFS 挂载和其他情况很重要,您可以通过不同的绝对路径访问相同的符号链接。例如

/net/tesla/home/peter/foo -> bar  # always works from other machines

/net/tesla/home/peter/foo -> /home/peter/bar  # references my home dir on the local machine, not tesla.
Run Code Online (Sandbox Code Playgroud)

Debian 有时会将符号链接安装到../../doc/whatever/whatever,而不是绝对符号链接目标,因此当 NFS 安装在其他地方时,或者在查看 chroot 而不chroot(8)进入它时,它会起作用。

每个 Unix 进程都有自己的 cwd。该pwd命令的存在只是为了打印它。

有关使用 POSIX 系统调用更改目录的更多信息,请参见:http : //pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html


正如其他人所说,~在路径用于任何事情之前由外壳扩展。使用~/bin/myprog在shell脚本将使得针对不同用户的工作方式不同。~/bin/foo和之间的区别在于/home/peter/bin/foo,其中一个对位置进行了硬编码,而另一个对其进行了参数化。将~版本称为相对路径是错误的(IMO)。

谈论“相对于环境变量”的事情只是令人困惑。在您使用它们的上下文中使用具有特定技术含义的术语的不同英语含义是不好的做法。

在损坏的系统上,使用HOME=a/relative/path,~/foo将扩展为相对路径。这根本不是一个可用的设置。

  • 谢谢你的回答,对我来说似乎是最全面的。我也有这样的印象,作者错误地将*规范路径*的概念混为一谈(作者在任何地方都没有提到)。例如,`/opt/kde3/bin/../lib` 被错误地归类为相对路径:它*是*绝对路径但*不是*规范路径。正如您所说,这只会让一切变得混乱,所以感谢您的澄清和与 NFS 相关的信息:)! (3认同)
  • 尽管如此,这些对我来说只是普通的日常概念。我认为有一张纸说我认识他们会很奇怪......但祝你好运,@WhiteWinterWolf,向所有喜欢看纸的人展示。:) (2认同)

Bas*_*tch 16

如果您$HOME/home/white/, ~/Documents(与 相同$HOME/Documents)被外壳程序(参见此处的解释)扩展为/home/white/Documents,这是一个绝对路径。

相对路径是不以/(shell 扩展后)开头的路径,例如../Documentsfoo/bar

一些旧的炮弹不扩大~(的方式bashtcshzsh等...做); 他们会认为~/Documents是一个以~;开头的相对路径。但是您通常没有像这样的目录名~(但您可能会创建一个mkdir '~',我不建议这样做)。