我通常使用 zsh,它提供了 chpwd() 钩子。即:如果 cwd 被内置 cd 更改,zsh 会自动调用方法 chpwd() 如果它存在。这允许设置依赖于 cwd 的变量和别名。
现在我想将我的 .zshrc 的这一部分移植到 bash,但发现 chpwd() 无法被 bash 识别。bash 中是否已经存在类似的功能?我知道重新定义 cd 有效(见下文),但我的目标是更优雅的解决方案。
function cd()
{
builtin cd $@
chpwd
}
您必须使用 DEBUGtrap
或PROMPT_COMMAND
.
例子:
trap chpwd DEBUG # calls the function before each command
PROMPT_COMMAND=chpwd # calls the function after each command
请注意,中定义的函数在每个PROMPT_COMMAND
提示之前运行,即使是空的。
一个更好的解决方案可能是定义一个自定义chpwd
钩子。
与其他现代 shell 相比,Bash 中没有设计完整的钩子系统。PROMPT_COMMAND
变量用作钩子函数,相当于precmd
ZSH中的钩子,fish_prompt
在Fish中。目前,ZSH 是我所知道的唯一chpwd
内置钩子的 shell。
PROMPT_COMMAND
如果设置,该值将被解释为在打印每个主要提示 ($PS1) 之前要执行的命令。
https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Bash-Variables
chpwd
钩入 Bash提供了一个技巧来chpwd
在 Bash 中基于PROMPT_COMMAND
.
# create a PROPMT_COMMAND equivalent to store chpwd functions
typeset -g CHPWD_COMMAND=""
_chpwd_hook() {
shopt -s nullglob
local f
# run commands in CHPWD_COMMAND variable on dir change
if [[ "$PREVPWD" != "$PWD" ]]; then
local IFS=$';'
for f in $CHPWD_COMMAND; do
"$f"
done
unset IFS
fi
# refresh last working dir record
export PREVPWD="$PWD"
}
# add `;` after _chpwd_hook if PROMPT_COMMAND is not empty
PROMPT_COMMAND="_chpwd_hook${PROMPT_COMMAND:+;$PROMPT_COMMAND}"
# example 1: `ls` list directory once dir is changed
_ls_on_cwd_change() {
ls
}
# append the command into CHPWD_COMMAND
CHPWD_COMMAND="${CHPWD_COMMAND:+$CHPWD_COMMAND;}_ls_on_cwd_change"
# or just use `ls` directly
CHPWD_COMMAND="${CHPWD_COMMAND:+$CHPWD_COMMAND;}ls"
资料来源:根据我的要点在 Bash 中创建 chpwd 等效挂钩。