我的bash
(4.1)目录堆栈通常具有十几个或更多条目。我想用 dirs
替换dirs -v
的输出,所以我再也不必用pushd
来玩“猜魔术数字”了。
我的部分解决方案
我将dirs
替换为使用 dirs -v
执行command
的函数:
dirs()
{
# "command" builtin prevents infinite recusion by suppressing lookup
# of function and alias names.
command dirs -v "${@}"
}
(更新:在pneumatics' suggestion,我现在使用
builtin
代替command
。它不能解决此问题,但是稍微安全些。)现在可以读取
dirs
输出,但是 pushd
和popd
仍然产生了旧的斜杠:$ 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...
用别名替换
dirs
函数后,得到相同((缺少))结果:alias dirs='command dirs -v "${@}"'
解决方法
我最终也通过覆盖
pushd
和popd
获得了想要的输出:pushd()
{
command pushd "${@}" >/dev/null &&
dirs
}
# popd is similar.
这可行,但是它需要覆盖三个内建而不是一个。另外,在我未曾想到的某些极端情况下,这可能是对
pushd
和popd
的不完美模仿。我宁愿只覆盖dirs
。我的问题
为什么不覆盖
dirs
起作用? 根据bash
的man
页面,在pushd
和popd
下:那么,为什么
pushd
和popd
似乎调用了内置的dirs
而不是函数或别名?关于
bash
文档的脚注dirs
online manual缺少说“也执行bashref.*
”的段落,但它们出现在man
页面bash.*
和builtins.*
中。我的bash
4.1文档和当前的4.4文档都以相同的方式不一致,这表明4.4(如果有的话)的行为相同。 最佳答案
根据我对bash source code的阅读, pushd
和 popd
都调用 dirs
内置自身(没有任何参数),而不是引用已定义的别名和函数。
尽管内建函数很少利用外部功能,但是当内建函数确实需要外部功能时,调用另一个内建函数似乎是先例。例如,当pushd
更改目录it calls the cd
builtin时。或者,当declare
需要输入类型时,将其转换为it calls the set
builtin。
如何解决这个问题?好吧,可以从源代码重新编译bash:让pushd
和popd
传递-v
参数是微不足道的。还可以在上游请求bash来添加一个环境变量,该环境变量在用作dirs
/pushd
的助手时定义了默认的popd
选项。但这似乎是最快的userland解决方案,就像您已经完成的一样:只需覆盖所有这三个即可。
关于bash - 如何覆盖插入和弹出的对dirs的自动调用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39715474/