bash $PWD 与 pwd 关于便携性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10795014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 02:23:45  来源:igfitidea点击:

$PWD vs. pwd regarding portability

bash

提问by helpermethod

I'm writing a shell script which parses the path of the current working directory (printing a like of all basenames above the current directory).

我正在编写一个 shell 脚本,它解析当前工作目录的路径(打印当前目录上方的所有基本名称)。

So far, I've been using the environment variable PWDto parse the path but I wonder if

到目前为止,我一直在使用环境变量PWD来解析路径,但我想知道是否

  • I can count on PWDto be always set
  • to give the same result on every platform
  • 我可以指望PWD总是设置
  • 在每个平台上给出相同的结果

Would it possibly be better to use the pwdshell-builtin? I need this script to run on as many platforms as possible, so I just wondered...

使用pwdshell-builtin可能会更好吗?我需要这个脚本在尽可能多的平台上运行,所以我只是想知道......

回答by Mat

POSIXrequires $PWDto be set in the following fashion:

POSIX需要$PWD按以下方式设置:

PWD  

This variable shall represent an absolute pathname of the current working directory. It shall not contain any components that are dot or dot-dot. The value is set by the cd utility, and by the sh utility during initialization.

PWD  

此变量应表示当前工作目录的绝对路径名。它不应包含点或点-点形式的任何组件。该值由 cd 实用程序设置,并在初始化期间由 sh 实用程序设置。

So you can rely on that being set – but do note "... an absolute path...", not theabsolute path.

所以,你可以依靠是集-但做笔记“......绝对路径...”,而不是绝对路径。

bash(at least recent versions) will remember what symlinks you followed when setting $PWD(and the pwdbuiltin). command pwd(that is, the external command) will not. So you'll get different results there, which might, or might not, be important for you. Use pwd -Pif you want a path without symlinks.

bash(至少最近的版本)会记住你在设置$PWD(和pwd内置)时遵循的符号链接。command pwd(即外部命令)不会。所以你会在那里得到不同的结果,这对你来说可能重要,也可能不重要。pwd -P如果您想要没有符号链接的路径,请使用。

Do note that the pwddocumentation states:

请注意,pwd文档指出:

If an application sets or unsets the value of PWD, the behavior of pwd is unspecified.

如果应用程序设置或取消设置 PWD 的值,则未指定 pwd 的行为。

So, don't do that :)

所以,不要那样做:)

In short, there is no winner here. The environment variable will be there in POSIX shells, as will the external command and possibly a built-in too. Choose the one that best fits your need, the important thing being whether you care about symlinks or not.

简而言之,这里没有赢家。环境变量将存在于 POSIX shell 中,外部命令也可能是内置命令。选择最适合您的需要,重要的是您是否关心符号链接。

回答by mouviciel

From that forum article, "$PWD vs `pwd`"which compares AIX 4.2.1, AIX 6, Sparc Solaris 10 and Redhat 5 enterprise with this regard:

该论坛文章“$PWD vs `pwd`”在这方面比较了 AIX 4.2.1、AIX 6、Sparc Solaris 10 和 Redhat 5 Enterprise:

  • there is no difference between $PWD and builtin pwd,

  • there is no difference between builtin pwd -P and /usr/bin/pwd.

  • $PWD 和内置密码没有区别,

  • 内置 pwd -P 和 /usr/bin/pwd 之间没有区别。

The former shows working directory with names of symbolic links whereas the latter displays actual path.

前者显示带有符号链接名称的工作目录,而后者显示实际路径。

The only discrepancy is that external command is in /usr/bin in most systems and /bin in Redhat.

唯一的区别是外部命令在大多数系统中位于 /usr/bin 中,而在 Redhat 中位于 /bin 中。

回答by Karoly Horvath

If you know that bash is available and the script is executed with it, PWDis safe.

如果您知道 bash 可用并且脚本是用它执行的,则PWD是安全的。

If, on some systems, only plain sh is available, use pwd.

如果在某些系统上只有普通的 sh 可用,请使用pwd.

回答by Izaak van Dongen

Another point to note is command substitutions are not generally safe on trailing newlines.

另一点要注意的是, 命令替换在尾随换行符上通常并不安全

This is obviously fairly contrived, but if you're really concerned about safely handling input you should be using "$PWD". See, for example:

这显然是相当人为的,但如果您真的很关心安全处理输入,您应该使用"$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"

It is possible to work around the command substitution but it is by no means pretty. You can append a trailing character and then strip it with a parameter expansion:

可以解决命令替换的问题,但它绝不是漂亮的。您可以附加一个尾随字符,然后使用参数扩展将其剥离:

$ pwd_guarded="$(pwd; printf '#')"
$ pwd_fixed="${pwd_guarded%$'\n'#}"
$ printf "%q\n" "$pwd_fixed"
$'/tmp/trailing_newline\n'
$ cd "$pwd_fixed"

This is particularly ugly because you then also have to strip the newline that pwdadds, which would normally have been stripped by the command substitution. This becomes a total mess if you don't resort to non-POSIX constructs like $'', so basically, just use "$PWD"if you care about these things. Of course it is perfectly reasonable to just not support trailing newlines in directory names.

这特别难看,因为您还必须删除pwd添加的换行符 ,这通常会被命令替换删除。如果您不$''使用像 之类的非 POSIX 构造,这将变得一团糟 ,所以基本上,"$PWD"如果您关心这些事情,就使用它。当然,在目录名称中不支持尾随换行是完全合理的。

回答by delicateLatticeworkFever

If it were me, I'd use pwdsince it is a built-in both for bash and sh. That does not mean they work identically in all respects, but if you are invoking it without options, that shouldn't matter.

如果是我,我会使用pwd它,因为它是 bash 和 sh 的内置工具。这并不意味着它们在所有方面都相同,但是如果您在没有选项的情况下调用它,那应该无关紧要。