10

OLDPWD is exported and passed to any children, but bash apparently clears OLDPWD whenever a child script is started:

$ cd /etc
$ cd
$ perl -e 'print "<$ENV{OLDPWD}>\n"'
</etc>
$ ksh  -c 'echo "<$OLDPWD>"'
</etc>
$ bash -c 'echo "<$OLDPWD>"'
<>

Any way to work around that other than creating an alias or dotting the child script or exporting some other variable with the same value, whenever I want to use $OLDPWD in a child script?

** UPDATE 2015/11/26 **

I filed a bash bug report and got this reply from Chet Ramey, the bash maintainer:

Why does bash clear OLDPWD when a child script is started?

Because a new shell does not have a `previous working directory'. It's supposed to be set by cd, and if you haven't executed cd, you don't have one.

It seems reasonable to inherit OLDPWD if it names a directory, in the same way that the shell inherits PWD if it names the current directory, so we'll try that for the next bash version.

1
  • Chet must be very careful. This seems to be a nice features, but it can break a lot of scripts, whom expect an empty OLDPWD
    – Massimo
    Apr 19, 2020 at 10:32

1 Answer 1

8

Probably this is leftover behavior from long ago when bash first implemented OLDPWD. The release notes for bash 2.03 alpha (in 1999) indicate that OLDPWD was previously not an exported variable. If it was not exported, it would not be inherited by a child process.

Judging by the comment on this chunk from bash's source, the behavior is intentional:

  /* 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));

Though the release note indicates that making it exported was done to follow POSIX.2, OLDPWD does not appear in the list of shell variables for POSIX shell. It does appear in the description of cd. That does not mention if an initial value should be obtained from a parent process; there is no specific behavior which is required.

It does not appear to be a documented feature of bash; there are few comments to be found:

3
  • "no prior cd command"...I remember a shell on Solaris where PWD was not set upon shell entry. I believe it was later fixed.
    – jrw32982
    Nov 14, 2015 at 19:13
  • Based on bash's behavior, it appears that although OLDPWD is exported by bash properly, bash refuses to import it into a new process (bash appears to unset OLDPWD upon entry).
    – jrw32982
    Nov 14, 2015 at 19:20
  • 1
    The way to resolve whether it was intentional or merely a minor bug overlooked for 25 years would be to file a bug report. Since the initial value of OLDPWD does not appear to be addressed by POSIX, the guiding constraint would be whether bash's developers intended to match the behavior of ksh, or not. Nov 14, 2015 at 19:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .