Есть ли крючок в 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 из моей сущности.