Silencing pushd/popd Directory Stack Output in Bash Shell Scripts


2 views

If you've used pushd and popd in bash scripts, you've probably noticed they always print the directory stack after execution. This behavior can clutter your script output and break clean logging patterns.

#!/bin/bash
pushd /tmp
# Output shows: /tmp ~
popd
# Output shows: ~

Here are three effective ways to suppress this output:

Method 1: Redirect to /dev/null

pushd /tmp > /dev/null
# Your commands here
popd > /dev/null

Method 2: Use a Wrapper Function

quiet_pushd() {
    pushd "$1" > /dev/null
}

quiet_popd() {
    popd > /dev/null
}

quiet_pushd /tmp
# No output
quiet_popd
# No output

Method 3: Modify Shell Options (Bash 4.3+)

# Disable directory stack printing globally
shopt -u cdable_vars
shopt -u cdspell

Silent directory changes are particularly useful in:

  • Deployment scripts where clean output matters
  • Cron jobs that email output
  • CI/CD pipelines parsing script output
  • Any situation where you chain multiple directory changes
#!/bin/bash
# Clean deployment example
quiet_pushd /build/directory
make install
quiet_popd

If you need even more control:

# Store current directory and change manually
ORIG_DIR=$(pwd)
cd /new/directory || exit 1
# Do work
cd "$ORIG_DIR"

If you've used pushd and popd in bash scripts, you've probably noticed they always print the directory stack after execution. While this can be useful for interactive use, it creates unwanted noise in scripts and automated processes.

$ pushd /tmp
/tmp ~
$ popd
~

The simplest solution is to redirect the output to /dev/null:

pushd /path/to/dir > /dev/null
# Your commands here
popd > /dev/null

This effectively silences the stack output while maintaining all functionality.

For frequent use, consider creating wrapper functions in your .bashrc:

quiet_pushd() {
    pushd "$1" > /dev/null
}

quiet_popd() {
    popd > /dev/null
}

# Usage:
quiet_pushd /var/log
# Do work here
quiet_popd

Bash maintains the directory stack in the DIRSTACK variable. You can manipulate it directly:

# Equivalent to pushd
DIRSTACK="$PWD ${DIRSTACK:-}"
cd /new/dir

# Equivalent to popd
cd ${DIRSTACK%% *}
DIRSTACK=${DIRSTACK#* }

Clean output is crucial for:

  • Parsing script output programmatically
  • Maintaining clean log files
  • Following Unix philosophy of silent operation
  • Preventing confusion in complex scripts

Remember that error messages will also be silenced with > /dev/null. To preserve errors while silencing normal output:

pushd /nonexistent 2>&1 > /dev/null | grep -v '^pushd:'

Or handle errors separately:

if ! pushd /dir > /dev/null; then
    echo "Failed to change directory" >&2
    exit 1
fi