My bash (4.1) directory stack usually has a dozen or more entries. I wanted to replace the output of dirs with dirs -v, so I would never have to play "guess the magic number" with pushd again.
My Partial Solution
I replaced dirs with a function that executed dirs -v using command:
dirs()
{
# "command" builtin prevents infinite recusion by suppressing lookup
# of function and alias names.
command dirs -v "${@}"
}
(Update: At pneumatics' suggestion, I now use builtin instead of command. It doesn't solve this problem, but it's slightly safer.)
dirs output was now readable, but pushd and popd still produced the old vomit-of-slashes:
$ pushd ~/just/one/more/and/ill/quit/i/promise
~/just/one/more/and/ill/quit/i/promise ~/tmp/bash/bash-4.1...
may/give/rise/to/dom /oh/no/not/again /var/adm/log /omg/wt...
va/lang ~/doc/comp/java/api/java/util/regex barf barf barf...
I got the same (lack of) result after replacing my dirs function with an alias:
alias dirs='command dirs -v "${@}"'
The Workaround
I eventually got the output I wanted by overriding pushd and popd as well:
pushd()
{
command pushd "${@}" >/dev/null &&
dirs
}
# popd is similar.
This works, but it requires overriding three builtins instead of one. Also, this could be an imperfect impersonation of pushd and popd in some corner case I haven't thought of. I'd rather override dirs only.
My Question
Why didn't overriding dirs work? According to bash's man page, under both pushd and popd:
If the
pushdcommand is successful, adirsis performed as well.
So why did pushd and popd appear to invoke the builtin dirs instead of the function or the alias?
Footnote about the bash Documentation
The paragraphs saying "a dirs is performed as well" are missing from the bashref.* online manual, but they appear in the man pages bash.* and builtins.*. Both my bash 4.1 docs and the current 4.4 docs are inconsistent in the same manner, which suggests that 4.4 (if I had it) would behave the same.