Есть ли крючок в Bash, чтобы узнать, когда изменится cwd?

Обычно я использую zsh, который предоставляет хук chpwd(). То есть: если cwd изменяется с помощью встроенного cd, zsh автоматически вызывает метод chpwd(), если он существует. Это позволяет настраивать переменные и псевдонимы, которые зависят от cwd.

Теперь я хочу перенести этот бит моего .zshrc в bash, но обнаружил, что chpwd() не распознается bash. Является ли аналогичная функциональность уже существующей в bash? Я знаю, что переопределение работы cd (см. Ниже), но я нацелен на более элегантное решение.

function cd()
{
    builtin cd [email protected]
    chpwd
}

Ответы

Ответ 1

Вам нужно будет использовать DEBUG trap или PROMPT_COMMAND.

Примеры:

trap chpwd DEBUG        # calls the function before each command

PROMPT_COMMAND=chpwd    # calls the function after each command

Обратите внимание, что функция, определенная в PROMPT_COMMAND, запускается до каждого, хотя и пустых.

Ответ 2

Лучшим решением может быть определение пользовательского хука chpwd.

По сравнению с другими современными оболочками в Bash не разработана полная система крючков. Переменная PROMPT_COMMAND используется в качестве функции ловушки, которая эквивалентна precmd в fish_prompt, fish_prompt в Fish. На данный момент ZSH - единственная из известных мне оболочек, в которой есть встроенный хук chpwd.

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"

Источник: Создать chvwd Equivalent Hook in Bash из моей сущности.