Есть ли в Bash хук, чтобы узнать, когда меняется cwd?
Я обычно использую zsh, который предоставляет хук chpwd(). То есть: если cwd изменяется встроенным cd, zsh автоматически вызывает метод chpwd(), если он существует. Это позволяет устанавливать переменные и псевдонимы, которые зависят от cwd.
Теперь я хочу перенести этот бит моего.zshrc на bash, но обнаружил, что chpwd() не распознается bash. Есть ли подобная функциональность в bash? Я знаю, что переопределение CD работает (см. Ниже), но я стремлюсь к более элегантному решению.
function cd()
{
builtin cd $@
chpwd
}
1 ответ
Вы должны использовать отладку trap
или же PROMPT_COMMAND
,
Примеры:
trap chpwd DEBUG # calls the function before each command
PROMPT_COMMAND=chpwd # calls the function after each command
Обратите внимание, что функция, определенная в PROMPT_COMMAND
запускается перед каждым приглашением, хотя и пустыми.
Лучшим решением могло бы быть определение пользовательскогоchpwd
крючок.
В Bash не существует полноценной системы хуков по сравнению с другими современными оболочками. PROMPT_COMMAND
переменная используется как функция-перехватчик, что эквивалентно precmd
крючок в ЗШ, fish_prompt
в Рыбе. На данный момент ZSH - единственная известная мне оболочка, имеющаяchpwd
встроенный крючок.
PROMPT_COMMAND
Если установлено, значение интерпретируется как команда, выполняемая перед печатью каждого основного приглашения ($PS1).
https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html
chpwd
Крючок в Баше
Предоставляется трюк для настройки 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"
Источник: Создайте перехватчик chpwd Equivalent Hook в Bash по моей сути.