bashshellscriptingstackpushd

bash: no need to call popd after pushd at the end of a script?


I was going through some trouble to do some proper "pushd/popd cleanup" in my bash script. That is: if I did pushd a few times, I wanted to make sure to do the same number of popd before exit.

However, I noticed that the pushd/popd stack doesn't seem to be global.

Suppose I have this script called example-pushd-twice.sh in my homedir:

pushd /etc
pushd /tmp

And I do this from the shell from within my homedir: (resulting output in blockquotes)

dirs

~

./example-pushd-twice.sh

/etc ~
/tmp /etc ~

I now expected to still be in /tmp and still having a dir stack with 3 dirs, however:

dirs

~

Is this correct behavior? Can I trust a shell script to invoke its own pushd/popd stack, so I don't have to care about cleaning up afterwards?


Solution

  • Directory stack is gone when the shell (interpreter of you script) exits. This is the same behavior you would get if you ran /bin/bash from your interactive shell. Did pushd /tmp. And then typed exit. The shell you are returning to is not affected by what happened inside that other bash process.

    However, in a situation when you source your script (i.e. you run the commands within current bash process) instead of executing it (creating new shell instance) the directory stack would still linger around after last line of sourced file finished. Instead of ./example-pushd-twice.sh run source ./example-pushd-twice.sh and observe the difference. For that reason, if you rely on pushd in your script, it would still be prudent to popd before it finishes.