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
pushd
command is successful, adirs
is 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.