1

我想知道内置 pwd 和 /bin/pwd 的代码实现,尤其是当目录路径是符号链接时。

例子:

hita@hita-laptop:/home$ ls -l
lrwxrwxrwx  1 root root   31 2010-06-13 15:35 my_shell -> /home/hita/shell_new/hita_shell

hita@hita-laptop:/home$ cd my_shell

hita@hita-laptop:/home/my_shell$ pwd <SHELL BUILT-IN PWD>  
/home/my_shell

hita@hita-laptop:/home/my_shell$ /bin/pwd  
/home/hita/shell_new/hita_shell

两种情况下的输出是不同的。有什么线索吗?

谢谢

4

4 回答 4

3

内核维护一个当前目录(通过inode),当您需要当前目录时,它通过向上遍历目录树(使用..)来查找所有路径组件的名称来确定其名称。这是“真正的”或有时称为“物理”的工作目录。有一个库函数 getcwd(3) 可以为您执行此操作;在较新的 Linux 系统上,这实际上是一个系统调用,如果父目录处于重命名过程中,它有助于获得一致的视图。

一些 shell,特别是 bash,维护一个环境变量 PWD 来跟踪你的位置,如果你通过符号链接更改目录,这个环境变量会显示出来。他们称之为“逻辑”路径。

/bin/pwd 显示getcwd(3)的结果,即真实路径;如果你给它 -L 它会告诉你 PWD 的价值(除非它是垃圾,否则你会得到真正的路径)。(Gnu 的 /bin/pwd 版本在处理没有读取权限和非常长的路径名的父目录的复杂性方面做得比这更多。)

Bash 的内置 pwd 向您显示“逻辑”路径以及您用来到达那里的任何符号链接;即使它现在是垃圾(即自从你使用它后被删除或重命名)。内置 pwd 的默认值可以使用 set -o physical (on) 或 set +o physical (off 是加号!) 更改默认提示符(包含当前目录)也跟随该选项。

# make a directory with a symlink alias
cd /tmp
mkdir real
ln -s real sym
cd sym

pwd  # will say sym
pwd -L # will say sym
pwd -P # will say real
/bin/pwd  # will say real
/bin/pwd -L # will say sym
/bin/pwd -P # will say real

rm /tmp/sym
pwd  # says sym, though link no longer exists
/bin/pwd -L # will say real!

rmdir /tmp/real
pwd  # says sym, though no directory exists
/bin/pwd # says error, as there isn't one

就其价值而言,我认为所有“合乎逻辑”的业务只会增加混乱;旧方法是更好的方法。确实,符号链接可能会令人困惑,但这会使它更加混乱,因为打开 .. 的任何文件操作与使用 .. 的任何目录更改都不会做同样的事情,例如在这个相当讨厌的例子中:

mkdir -p /tmp/dir/subdir
ln -s /tmp/dir/subdir /tmp/a
cd /tmp/a
ls .. # shows contents of /tmp/dir
(cd .. ; ls) # shows contents of /tmp

为了避免这一切,您可以将以下内容放入您的 ~/.bashrc set -o physical

希望有帮助!

亲切的问候,J。

PS 以上是非常特定于 Linux 和 Gnu bash 的;其他外壳和系统相似但不同。

于 2014-05-23T09:18:27.653 回答
2

shell 的内置 pwd 的优点是能够记住您如何访问符号链接目录,因此它会向您显示该信息。独立实用程序只知道您的实际工作目录是什么,而不是您如何更改到该目录,因此它会报告真实路径。

就个人而言,我不喜欢执行您所描述的外壳,因为它显示的现实与独立工具将看到的不同。例如,内置工具解析相对路径的方式与独立工具解析相对路径的方式不同。

于 2010-06-28T17:12:24.660 回答
1

cdshell 通过将它与您要连接的任何内容(并消除...条目)连接起来,在自己的内存中跟踪您当前的目录是什么。这样做是为了避免符号链接混乱cd ..。该/bin/pwd实现向上遍历目录树,试图找到具有正确名称的 inode。

于 2010-06-28T17:13:28.080 回答
1

默认情况下,内置显示符号链接,但如果你给它选项pwd就不会这样做。-P

相反,该pwd命令默认情况下不显示符号链接,但如果给定-L选项就会显示。

于 2010-06-28T17:14:22.033 回答