Answers:
在包括bash在内的大多数shell中,pwd都是内置的shell:
$ type -a pwd
pwd is a shell builtin
pwd is /bin/pwd
如果使用/bin/pwd,则必须使用该-L选项来获得与内置相同的结果pwd:
$ ln -s . test
$ cd test && pwd
/home/cuonglm/test
$ /bin/pwd
/home/cuonglm
$ /bin/pwd -L
/home/cuonglm/test
默认情况下,/bin/pwd忽略符号链接并打印实际目录。
来自info pwd:
`-L'
`--logical'
If the contents of the environment variable `PWD' provide an
absolute name of the current directory with no `.' or `..'
components, but possibly with symbolic links, then output those
contents. Otherwise, fall back to default `-P' handling.
`-P'
`--physical'
Print a fully resolved name for the current directory. That is,
all components of the printed name will be actual directory
names--none will be symbolic links.
内置pwd默认情况下包括符号链接,不同之处在于-P使用了该选项或-o physical启用了内置设置。
来自man bash:
pwd [-LP]
Print the absolute pathname of the current working directory.
The pathname printed contains no symbolic links if the -P option
is supplied or the -o physical option to the set builtin command
is enabled. If the -L option is used, the pathname printed may
contain symbolic links. The return status is 0 unless an error
occurs while reading the name of the current directory or an
invalid option is supplied.
/bin/pwd默认情况下忽略符号链接,请阅读info pwd我的答案:为当前目录打印一个完全解析的名称。也就是说,打印名称的所有组成部分将是实际目录名称- 没有一个将是符号链接。
set -o physical,现在默认情况下pwd是use -P选项,如果没有-L选项,如何打印包含符号链接的路径?阅读此内容https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html以了解set -o physical功能。
一个过程可能会查询文件系统以确定其当前工作目录,使用的方法有点过于复杂,以至于无法作为主题来回答该问题。这就是pwd程序和getcwd库函数的作用。在Unix的早期,它们是找出工作目录是什么的唯一方法。这是您所提问题的一部分,在其他任何答案中,甚至在本网站的其他任何地方(经过42秒的搜索之后),我都找不到:
getcwd)。此后,只要你做了cd,pushd或popd,外壳跟踪使用字符串处理函数的工作目录。例如,
/home/sim且键入cd ..,则Shell将计算您的工作目录为/home。/home/sim并且键入cd .,则Shell将计算出您的工作目录仍然是/home/sim。/home/sim并且键入cd aa,则Shell将计算出您的工作目录为/home/sim/aa -无需检查是否aa为符号链接。这样做是为了节省通话的“成本” getcwd。但这是一个折衷,因为它可能导致错误的信息。
pwd(内置)命令只显示shell的记忆/计算的工作目录是什么概念。因此,最重要的是,外壳可能对其所在位置感到困惑。但是,如果您键入/bin/pwd,它将在一个单独的进程中运行,而该进程无法访问外壳程序关于工作目录的概念,因此它可以确定老式的工作目录本身。(例外:该/bin/pwd程序可以查看PWD环境变量,并且当您指定时显然也可以-L。)这是另一个如何使Shell感到困惑的示例:
cd /home/sim/aa #假设/home,/home/sim和/home/sim/aa
#都是真正的目录(而不是符号链接)。
pwd #输出:/home/sim/aa,这是正确的。
mv ../aa ../bb
pwd #输出:/home/sim/aa,这是不正确的。
/bin/pwd #输出:/home/sim/bb,这是正确的。
而且,以防万一您不清楚,如果您键入ln -s . aaand cd aa,那么您当前的工作目录不会发生变化,与您键入时所做的一样多,cd .因为,这实际上是您键入时所做的cd aa。
-L除了节省成本之外,还有很多事情 -并且$PWD是用户定义的POSIX指定的环境变量-用户空间应用程序可能应该信任它 (这意味着...?)。无论如何,尽管我根本不喜欢符号链接,但用户有特权在许多疯狂的方向上进行间接操作,而这些方向应该由他或她选择,这-L是最重要的。