【问题标题】:$PWD vs. pwd regarding portability$PWD 与 pwd 关于可移植性
【发布时间】:2012-05-29 07:46:03
【问题描述】:

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

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

  • 我可以指望PWD 始终被设置
  • 在每个平台上提供相同的结果

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

【问题讨论】:

    标签: bash


    【解决方案1】:

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

    PWD  
    

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

    因此,您可以依赖该设置 - 但请注意“...绝对路径...”,而不是 绝对路径。

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

    请注意pwd 文档指出:

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

    所以,不要那样做:)

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

    【讨论】:

    • POSIX 还说:“如果应用程序设置或取消设置 PWD 的值,则 pwd 的行为未指定”。可能希望将其包含在您的答案中。它明确说明这两种选择都不是“首选”(除非取决于您是否需要符号链接)
    • 如果当前工作目录被删除,pwd 命令将导致错误。 $PWD 现在仍然显示不存在的目录。
    【解决方案2】:

    从那篇论坛文章"$PWD vs `pwd`" 中比较了 AIX 4.2.1、AIX 6、Sparc Solaris 10 和 Redhat 5 企业版:

    • $PWD和内置pwd没有区别,

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        还有一点需要注意的是 command substitutions are not generally safe on trailing newlines.

        这显然是相当做作的,但如果你真的担心安全 处理您应该使用"$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"。当然 不支持目录中的尾随换行符是完全合理的 名字。

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-03-18
            相关资源
            最近更新 更多