The use of the directory in scripts is questionable because it's risk-prone. popd
doesn't return to the original directory, it returns to the directory with the same name. If the original directory has been moved, your script will switch locations midway. This may seem like a remote risk, but sooner or later this will happen and the users of the script will curse you.
If you want to temporarily act in a different directory, the best way is to run that part of the script in a subshell.
( set -e
cd "${TMPDIR:-/tmp}"
wget -q http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz
cd redis-stable
make
sudo make install
)
Just for the sake of the example, I'll show alternative approaches which are not necessary here but can be useful in similar situations where a subshell is not suitable, e.g. because you want to set some variables and have them available after returning to the original directory.
You might not actually need to switch to a different directory, or only for the duration of an individual command. If you're using GNU tools, both tar
and make
support a -C
argument to switch to a directory. Given that you're creating that directory in your script, unlike the original directory, it is a reasonable assumption that its location won't move.
set -e
: "${TMPDIR:=/tmp}"
wget -q -O "$TMPDIR/redis-stable.tar.gz" http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz -C "$TMPDIR"
make -C "$TMPDIR/redis-stable"
sudo make -C "$TMPDIR/redis-stable" install
With commands that don't have an option to switch to a different directory, you can use a subshell with a narrow scope.
set -e
: "${TMPDIR:=/tmp}"
( cd "$TMPDIR"
wget -q http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz -C "$TMPDIR"
)
( cd "$TMPDIR/redis-stable"
make
sudo make install
)
If you really need to switch back and forth, the obvious improvement to multiple calls to popd
is to call cd
when you mean cd
, instead of calling pushd
for a directory you don't want to return to.
set -e
pushd "${TMPDIR:-/tmp}"
wget -q http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz
cd redis-stable
make
sudo make install
popd
But I'd really recommend not using pushd
and popd
at all. They're meant for interactive use, and in scripts they tend to be more confusing than anything. If you want to save the location of the current directory, save it in a variable. This makes your script easier to read, this way the reader doesn't have to figure out where a popd
call will return.
set -e
original_directory="$PWD"
cd "${TMPDIR:-/tmp}"
wget -q http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz
cd redis-stable
make
sudo make install
cd "$original_directory"
mypopd 5
, or would it always be to the top?mypopd 5
, otherwise the user has to give up a certain degree of control over how far it goes.