我正在编写一个解析当前工作目录路径的 shell 脚本(打印当前目录上方的所有基本名称)。
到目前为止,我一直在使用环境变量PWD
来解析路径,但我想知道是否
- 我可以指望
PWD
始终如一 - 在每个平台上给出相同的结果
pwd
使用shell-builtin会更好吗?我需要这个脚本在尽可能多的平台上运行,所以我只是想知道......
我正在编写一个解析当前工作目录路径的 shell 脚本(打印当前目录上方的所有基本名称)。
到目前为止,我一直在使用环境变量PWD
来解析路径,但我想知道是否
PWD
始终如一pwd
使用shell-builtin会更好吗?我需要这个脚本在尽可能多的平台上运行,所以我只是想知道......
POSIX需要$PWD
按以下方式设置:
PWD
该变量应代表当前工作目录的绝对路径名。它不应包含任何点或点-点的组件。该值由 cd 实用程序和 sh 实用程序在初始化期间设置。
所以你可以依赖这个设置——但请注意“......绝对路径......”,而不是绝对路径。
bash
(至少是最新版本)会记住您在设置$PWD
(和pwd
内置)时遵循的符号链接。command pwd
(即外部命令)不会。所以你会在那里得到不同的结果,这可能对你很重要,也可能不重要。pwd -P
如果您想要没有符号链接的路径,请使用。
请注意,pwd
文档指出:
如果应用程序设置或取消设置 PWD 的值,则未指定 pwd 的行为。
所以,不要那样做:)
简而言之,这里没有赢家。环境变量将存在于 POSIX shell 中,外部命令也可能存在,也可能是内置命令。选择最适合您需要的那个,重要的是您是否关心符号链接。
该论坛文章“$PWD vs `pwd`”在这方面比较了 AIX 4.2.1、AIX 6、Sparc Solaris 10 和 Redhat 5 企业版:
$PWD 和内置密码没有区别,
内置 pwd -P 和 /usr/bin/pwd 之间没有区别。
前者显示带有符号链接名称的工作目录,而后者显示实际路径。
唯一的差异是外部命令在大多数系统中位于 /usr/bin 中,而在 Redhat 中位于 /bin 中。
如果您知道 bash 可用并且使用它执行脚本,那么它PWD
是安全的。
如果在某些系统上只有普通的 sh 可用,请使用pwd
.
另一点需要注意的是 命令替换在尾随换行符上通常是不安全的。
这显然是相当做作的,但如果您真的关心安全处理输入,您应该使用"$PWD"
. 参见,例如:
$ my_dir=$'/tmp/trailing_newline\n'
$ mkdir -p "$my_dir"
$ cd "$my_dir"
$ pwd
/tmp/trailing_newline
$ printf "%q\n" "$(pwd)" "$PWD"
/tmp/trailing_newline
$'/tmp/trailing_newline\n'
$ cd "$(pwd)"
sh: cd: /tmp/trailing_newline: No such file or directory
$ cd "$PWD"
可以解决命令替换,但这绝不是漂亮的。您可以附加一个尾随字符,然后使用参数扩展将其剥离:
$ pwd_guarded="$(pwd; printf '#')"
$ pwd_fixed="${pwd_guarded%$'\n'#}"
$ printf "%q\n" "$pwd_fixed"
$'/tmp/trailing_newline\n'
$ cd "$pwd_fixed"
这特别难看,因为您还必须删除
pwd
添加的换行符,这通常会被命令替换删除。如果您不求助于非 POSIX 结构,这将变得一团糟
$''
,所以基本上,只要"$PWD"
您关心这些事情,就可以使用。当然,不支持目录名称中的尾随换行符是完全合理的。
如果是我,我会使用它,pwd
因为它是 bash 和 sh 的内置工具。这并不意味着它们在所有方面都相同,但是如果您在没有选项的情况下调用它,那应该没关系。