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 . aa
and cd aa
,那么您当前的工作目录不会发生变化,与您键入时所做的一样多,cd .
因为,这实际上是您键入时所做的cd aa
。
-L
除了节省成本之外,还有很多事情 -并且$PWD
是用户定义的POSIX指定的环境变量-用户空间应用程序可能应该信任它 (这意味着...?)。无论如何,尽管我根本不喜欢符号链接,但用户有特权在许多疯狂的方向上进行间接操作,而这些方向应该由他或她选择,这-L
是最重要的。