为什么 bash 在启动子脚本时会清除 OLDPWD?

jrw*_*982 9 bash environment-variables

OLDPWD 被导出并传递给任何子脚本,但是每当子脚本启动时,bash 显然会清除 OLDPWD:

$ cd /etc
$ cd
$ perl -e 'print "<$ENV{OLDPWD}>\n"'
</etc>
$ ksh  -c 'echo "<$OLDPWD>"'
</etc>
$ bash -c 'echo "<$OLDPWD>"'
<>
Run Code Online (Sandbox Code Playgroud)

每当我想在子脚本中使用 $OLDPWD 时,除了创建别名或添加子脚本或导出具有相同值的其他变量之外,还有什么方法可以解决这个问题?

** 更新 2015/11/26 **

我提交了一份 bash 错误报告,并从 bash 维护者 Chet Ramey 那里得到了这个回复:

为什么 bash 在启动子脚本时会清除 OLDPWD?

因为新的 shell 没有“以前的工作目录”。它应该是由cd设置的,如果你没有执行过cd,你就没有。

如果 OLDPWD 命名目录,则继承 OLDPWD 似乎是合理的,就像 shell 命名当前目录时继承 PWD 一样,因此我们将在下一个 bash 版本中尝试这样做。

Tho*_*key 6

这可能是很久以前首次实施 bash 时遗留的行为OLDPWD。bash 2.03 alpha(1999 年)的发行说明表明它OLDPWD以前不是导出变量。如果它没有被导出,它就不会被子进程继承。

从 bash 来源对该块的评论来看,这种行为是故意的:

  /* According to the Single Unix Specification, v2, $OLDPWD is an
     `environment variable' and therefore should be auto-exported.
     Make a dummy invisible variable for OLDPWD, and mark it as exported. */
  temp_var = bind_variable ("OLDPWD", (char *)NULL, 0);
  VSETATTR (temp_var, (att_exported | att_invisible));
Run Code Online (Sandbox Code Playgroud)

尽管发行说明表明将其导出是为了遵循 POSIX.2,OLDPWD但并未出现在POSIX shell的shell 变量列表中。它确实出现在 的描述中cd。这并没有提到是否应该从父进程获取初始值;没有需要的特定行为。

它似乎不是 bash 的记录功能;有几个评论可以找到: