OLDPWD 被导出并传递给任何子脚本,但 bash 显然会在子脚本启动时清除 OLDPWD:
$ cd /etc
$ cd
$ perl -e 'print "<$ENV{OLDPWD}>\n"'
</etc>
$ ksh -c 'echo "<$OLDPWD>"'
</etc>
$ bash -c 'echo "<$OLDPWD>"'
<>
每当我想在子脚本中使用 $OLDPWD 时,除了创建别名或点子脚本或导出具有相同值的其他变量之外,有什么方法可以解决这个问题?
** 更新 2015/11/26 **
我提交了一份 bash 错误报告,并得到了 bash 维护者 Chet Ramey 的回复:
为什么当子脚本启动时 bash 会清除 OLDPWD?
因为新的 shell 没有“以前的工作目录”。应该是通过cd来设置的,如果你没有执行过cd,那么你就没有。
如果命名一个目录,则继承 OLDPWD 似乎是合理的,就像 shell 命名当前目录时继承 PWD 一样,所以我们将在下一个 bash 版本中尝试这样做。
答案1
这可能是很久以前 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));
尽管发行说明表明导出它是为了遵循 POSIX.2,OLDPWD
并未出现在列表中外壳变量对于 POSIX shell。它确实出现在描述中cd
。这并没有提到是否应该从父进程获取初始值;没有要求特定的行为。
它似乎不是 bash 的记录功能;发现评论很少:
- MacOSX 上 Erlang 中的 OLDPWD 丢失
- ...“OLDPWD 未设置”...,指出最初子 shell有没有事先
cd
设置的命令$OLDPWD
。