which
command reminded me of another wrapper function that's handy to have. If you use pushd/popd
to keep a stack of directories in your shell window, sometimes you want to switch to a directory far down the stack. If you want to switch to the third directory down, you do pushd +3
.The problem is, you have to count along the list of directories, since
dirs, pushd,
and popd
all just spit out a one-line list of the stack, like this:Not an impossible task, but it can get annoying if you have some long paths in there, especially once your stack gets past two or three deep. Why not have
$ dirs
/usr/local/share ~ ~/work ~/tmp
dirs
print one directory per line, and label them with their depths? To do so, add this function to your .bashrc
file:Now you get more readable output:
function dirs {
ds=(`command dirs`)
i=0
while [ "${ds[$i]}" != "" ]; do
echo $i: ${ds[$i]};
i=$((i+1));
done
}
If you want to remove
$ dirs
0: /usr/local/share
1: ~
2: ~/work
3: ~/tmp
~/work
from the stack, just do popd +2
.Since
pushd
and popd
also print the directory stack, let's add the same style of output to them:One final note. In case some wacky systemwide file has aliased these commands to something else, add the following unaliasing code to the top of your .bashrc:
function pushd {
if command pushd $@ > /dev/null; then
dirs
fi
}
function popd {
if command popd $@ > /dev/null; then
dirs
fi
}
Otherwise, your functions will be hidden (aliases take precedence).
for func in dirs pushd popd; do
if alias $func > /dev/null 2>&1 ; then unalias $func; fi
done
PS: emacs shell-mode has a conflict with this dirs: here's how to fix it.