pushd/popd for scripts that cd into many directories
If a bash function does cd somewhere and returns without cd - back, the caller is now in a different directory. This is a nightmare in Makefiles and deploy scripts where the same shell runs several build steps. pushd and popd make a stack out of the CWD so nesting is safe.
build_component() {
local dir="$1"
pushd "$dir" >/dev/null
trap 'popd >/dev/null' RETURN
make clean
make build
make test
}
build_component ./services/api
build_component ./services/worker
# CWD is wherever the caller started.
trap ... RETURN runs on function return (bash only, not POSIX sh). It fires even if set -e aborts the function mid-way, which is the thing you actually want: the caller never sees a moved CWD.
If you cannot use bash, the portable form is:
build_component() {
(
cd "$1" || exit 1
make clean
make build
make test
)
}
The subshell gives you an isolated CWD for free: the parent never leaves its original directory. Slightly more expensive (fork) but bullet-proof across shells.
See also /snippets/bash-trap-cleanup-tmpdir/.