1. Overview

In this tutorial, we’ll learn about the pushd command and cover its alternatives for the systems where it is unavailable.

2. The pushd Command

The pushd command is like the cd command, but with extra features. It allows us to quickly switch between directories without repeatedly typing the full directory paths:

$ pwd
/tmp
$ pushd /var # Push /var to the directory stack
/var /tmp
$ pwd
/var
$ popd
/tmp
$ pwd # Back to /tmp
/tmp

Here, we start at /tmp and push the /var directory. Then, we use popd to go back to /tmp without typing its full path.

3. Fixing the “pushd: Not Found” Error

pushd is a Bash-specific command which is not present in other shells like ash or dash. So, in these non-Bash shells, we get the “pushd: Not Found” error:

$ pushd /
sh: pushd: not found

So, we must make our programs use Bash to execute shell commands if we want to use the pushd command.

3.1. Shell Scripts

In Linux, the shebang specifies the interpreter for a script. Sometimes, scripts make the wrong assumption about /bin/sh always being a Bash shell. Hence, we must change the shebang to #!/bin/bash to make Bash run the script:

$ cat good.sh
#!/bin/bash
pushd /
$ ./good.sh
/ /tmp

We can see that the good.sh script works fine on systems where /bin/sh is not a Bash shell.

3.2. Makefiles

Similar to the above solution, we can set the interpreter for scripts inside Makefiles with the SHELL variable. We can either set SHELL = /bin/bash at the top of the Makefile or set it externally when executing make:

$ cat Makefile 
all:
    pushd /
$ make SHELL=/bin/bash
pushd /
/ /tmp

4. A Portable Alternative to pushd

The pushd command is unavailable on systems where bash isn’t installed, but we can use subshells to mimic its behavior. Any command surrounded by parenthesis runs in a separate shell and doesn’t affect the current shell.

Let’s mimic the same example from earlier:

$ cat subshell.sh 
#!/bin/sh

echo "In $(pwd)"

(
    cd /usr; echo "In $(pwd)"
    (
        cd /var; echo "In $(pwd)"
    )
    echo "Back to $(pwd)"
)

echo "Back to $(pwd)"
$ ./subshell.sh 
In /tmp
In /usr
In /var
Back to /usr
Back to /tmp

As we can see, we followed the same path from /tmp to /var and back to /tmp. However, we must note that pushd provides some more features like directory enumeration, which can’t be replicated in this manner.

5. Conclusion

In this article, we covered the uses of the pushd command and learned how to mimic its behavior on systems where it’s not available.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.