我想知道内置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
两种情况下的输出都不同。任何线索?
感谢
答案 0 :(得分:3)
内核维护当前目录(通过inode),当您需要当前目录时,它通过向上走目录树(使用..)来确定其名称,以查找所有路径组件的名称。这是“真正的”或有时称为“物理”工作目录。有一个库函数getcwd(3)为你做这个;在更新的Linux系统上,这实际上是一个系统调用,如果父目录正在被重命名,这有助于获得一致的视图。
有些shell,特别是bash,维护一个环境变量PWD来跟踪你的位置,如果你通过符号链接更改了目录,这个环境变量就会显示出来。他们称之为“逻辑”路径。
/ bin / pwd显示getcwd(3)的结果,即实际路径;如果你给它-L它将告诉你PWD的价值(除非它是垃圾,然后你得到真正的道路)。 (Gnu的/ bin / pwd版本做了比这更多的工作来处理没有读取权限和很长路径名的父目录的复杂性。)
Bash的内置密码显示了你用来到那里的任何符号链接的“逻辑”路径;即使它现在是垃圾(即你使用它后删除或重命名)。可以使用set -o physical(on)或set + o physical(off is plus!)更改内置pwd的默认值。默认提示符(包含当前目录)也在该选项后面。
# 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中添加以下内容 设置-o physical
希望有所帮助!
亲切的问候, 学家
PS以上内容非常适用于Linux和Gnu bash;其他炮弹和系统相似但不同。
答案 1 :(得分:2)
shell的内置密码具有以下优点:能够记住您访问符号链接目录的方式,因此它会向您显示该信息。独立实用程序只知道您的实际工作目录是什么,而不是您更改到该目录的方式,因此它会报告实际路径。
就个人而言,我不喜欢做你所描述的贝壳,因为它显示的是与独立工具所看到的不同的现实。例如,内置工具如何解析相对路径将与独立工具解析相对路径的方式不同。
答案 2 :(得分:1)
shell通过将其与cd
的任何内容连接起来(以及消除.
和..
条目),在自己的内存中跟踪您的当前目录。它这样做是为了使符号链接不会弄乱cd ..
。 /bin/pwd
实现向上遍历目录树,尝试查找具有正确名称的inode。
答案 3 :(得分:1)
默认情况下,内置pwd
会显示符号链接,但如果您为其提供-P
选项,则不会执行此操作。
相比之下,pwd
命令默认情况下不显示符号链接,但如果给出-L
选项则会显示。