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.