Background
Long story short, I’m using an Alpine container that has BusyBox as its Shell implementation. Honestly, the more I’ve used it, the more comfortable I’ve become with it, but it’s missing one of my preferred Shell builtins: pushd
and popd
. I wrote a simplistic implementation in a *.sh
file, and you can find it below.
Question
How do I persist the stack with proper isolation between multiple processes and users?
Original Code
pushd() {
if ! test -f ~/pushd; then
echo -n "$(pwd)" > ~/pushd
else
echo -n "$(pwd):$(cat ~/pushd)" > ~/pushd
fi
cd "$1"
}
popd() {
if ! test -f ~/pushd; then
return 0;
fi
cd "$(cut -d ':' -f1 ~/pushd)"
echo -n "$(cut -d ':' -f2- ~/pushd)" > ~/pushd
if test $(stat -c '%s' ~/pushd) -eq 0; then
rm ~/pushd
fi
}
Problems
Given the nature of a Docker container, it will generally be single-user, but it can spawn multiple shells and sub-shells, so I wanted to be able to support that. However, when I looked into the GNU Bash implementation of pushd/popd, it relies on a persistent data store that resides as a runtime allocation of the shell itself. Writing an application that provides this capability as a CLI tool means it will live only long enough for the directory change.
As you can see in my naive solution, I’m writing the “stack” to a file and using cut
to grab the previous location. Is this the approach I should use? Should I switch to a binary encoding, or would a raw string be sufficient? Is there an API for me to leverage the internals of BusyBox for persisting this stack for the lifetime of the current shell?
2