CDPATH 行为在 bourne shell (/bin/sh) 中是否被破坏

onl*_*one 2 linux shell bash cd-command

我有以下脚本:

#!/bin/sh

mkdir -p /tmp/test/foo

cd /tmp/test

unset CDPATH
echo "TEST1: Current working directory: ${PWD}"
echo "TEST1: attempting to 'cd foo'"
cd foo
echo "TEST1: Current working directory: ${PWD}"

cd /tmp/test
CDPATH=/tmp
echo "TEST2: Current working directory: ${PWD}"
echo "TEST2: attempting to 'cd foo'"
cd foo
echo "TEST2: Current working directory: ${PWD}"
Run Code Online (Sandbox Code Playgroud)

打印出来:

$ ./cdpath.sh
TEST1: Current working directory: /tmp/test
TEST1: attempting to 'cd foo'
TEST1: Current working directory: /tmp/test/foo
TEST2: Current working directory: /tmp/test
TEST2: attempting to 'cd foo'
./cdpath.sh: line 17: cd: foo: No such file or directory
TEST2: Current working directory: /tmp/test
Run Code Online (Sandbox Code Playgroud)

但是,如果我运行它/bin/bash cdpath.sh没有错误,并且TEST2输出与TEST1. 仅当我使用/bin/sh. 我还没有找到任何关于 bourne 和 bourne again shells 以不同方式解释 CDPATH 的文档:

http://tldp.org/LDP/abs/html/internalvariables.html#CDPATHREF http://tldp.org/LDP/abs/html/internal.html#CDREF

onl*_*one 7

经过更多的谷歌搜索和源代码检查,我发现我看到这种行为的原因是我正在运行 bash 3.2。在这个版本的 bash 中,如果您在 posix 模式下运行(当您通过 运行 bash 时会发生这种情况/bin/sh)并且CDPATH已设置,则cd不会搜索当前目录,除非它在CDPATH. 包含此行为是为了符合POSIX.2( IEEE 1003.2-1992)。这反映了他们的手册当时指定的内容。但是,对于 bash 4.2,他们更改了 posix 模式下的行为以匹配更新POSIX.1-2008,现在指定cd应始终搜索当前工作目录,即使CDPATH不包含它。Bash 的新手册 现在不再将此作为 posix 和非 posix 模式之间的区别包括在内,因为它不再不同。

他们通过在 posix 模式下用#if 0块包围它来禁用引发错误的代码来进行更改builtins/cd.def

#if 0
      /* changed for bash-4.2 Posix cd description steps 5-6 */
      /* POSIX.2 says that if `.' does not appear in $CDPATH, we don't
         try the current directory, so we just punt now with an error
         message if POSIXLY_CORRECT is non-zero.  The check for cdpath[0]
         is so we don't mistakenly treat a CDPATH value of "" as not
         specifying the current directory. */
      if (posixly_correct && cdpath[0])
        {
          builtin_error ("%s: %s", dirname, strerror (ENOENT));
          return (EXECUTION_FAILURE);
        }
#endif
Run Code Online (Sandbox Code Playgroud)

我希望当前的 bash 文档指出旧版本的 bash 具有这种行为的事实。