18

我通常使用 zsh,它提供了 chpwd() 钩子。即:如果 cwd 被内置 cd 更改,zsh 会自动调用方法 chpwd() 如果它存在。这允许设置依赖于 cwd 的变量和别名。

现在我想将我的 .zshrc 的这一部分移植到 bash,但发现 chpwd() 无法被 bash 识别。bash 中是否已经存在类似的功能?我知道重新定义 cd 有效(见下文),但我的目标是更优雅的解决方案。

function cd()
{
    builtin cd $@
    chpwd
}
4

2 回答 2

14

您必须使用 DEBUGtrapPROMPT_COMMAND.

例子:

trap chpwd DEBUG        # calls the function before each command

PROMPT_COMMAND=chpwd    # calls the function after each command

请注意,中定义的函数在每个PROMPT_COMMAND提示之前运行,即使是空的。

于 2010-07-18T16:20:32.173 回答
2

一个更好的解决方案可能是定义一个自定义chpwd钩子

与其他现代 shell 相比,Bash 中没有设计完整的钩子系统。PROMPT_COMMAND变量用作钩子函数,相当于precmdZSH中的钩子,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 等效挂钩。

于 2019-07-20T03:19:10.270 回答