Есть ли в Bash возможность узнать, когда меняется cwd?
Вопрос
Обычно я использую zsh, который предоставляет хук chpwd().То есть:Если cwd изменяется встроенной функцией cd, zsh автоматически вызывает метод chpwd(), если он существует.Это позволяет настраивать переменные и псевдонимы, которые зависят от cwd.
Теперь я хочу перенести этот фрагмент моего .zshrc в bash, но обнаружил, что bash не распознает chpwd().Существует ли подобная функциональность в bash?Я знаю, что переопределение cd работает (см. ниже), но я стремлюсь к более элегантному решению.
function cd()
{
builtin cd $@
chpwd
}
Решение
Вам придется использовать DEBUG 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
крюк в ZSH, fish_prompt
в Рыбе.На данный момент ZSH - единственная известная мне оболочка, которая имеет chpwd
встроенный крючок.
ПОДСКАЗКА_КОМАНДЫ
Если задано, значение интерпретируется как команда, которую необходимо выполнить перед печатью каждого основного приглашения ($PS1).
https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Bash-Variables
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 Хук в Bash из моей сути.