zsh предоставляет несколько приятных функций ловушки , в том числе chpwd
для запуска функции после того, как пользователь меняет каталоги.
# zsh only
function greet() { echo 'hi'; }
chpwd_functions+=("greet")
cd .. # hi
pushd # hi
popd # hi
Я пытаюсь подражать этому в bash.
Ограничения:
- Он должен работать как в интерактивных, так и в неинтерактивных оболочках, что, я думаю, означает, что он не может полагаться на что-то вроде
$PROMPT_COMMAND
- Он не может переопределить
cd
, потому что я хочу, чтобы он работал для любой команды, которая изменяет каталоги (например,pushd
иpopd
) - Он должен запускаться после команды пользователя, поэтому
trap "my_function" DEBUG
не работает, если я не могу как-то сказать там: «сначала запусти$BASH_COMMAND
мы в ловушке, а затем сделай это ...» Я вижу, что могу избежать автоматического запуска,$BASH_COMMAND
еслиextdebug
включен и функция trap возвращает 1, но я не думаю, что хочу форсироватьextdebug
, и возвращение1
для успешной (но измененной) команды кажется неправильным.
Последняя часть - «беги за командой пользователя» - это то, что меня сейчас озадачило. Если я могу запускать функцию после каждой команды, я могу проверить, изменился ли каталог с момента последней проверки. Например:
function check_pwd() {
# true in a new shell (empty var) or after cd
if [ "$LAST_CHECKED_DIR" != "$PWD" ]; then
my_function
fi
LAST_CHECKED_DIR=$PWD
}
Я на правильном пути или есть лучший путь? Как я могу запустить команду в bash после того, как пользователь сменит каталоги?
cd
,pushd
иpopd
? Сколько еще способов изменить каталог?cd
в качестве принципа.MYBIN=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )
, не меняйте доверенные команды Unix.bash
, которая работает практически одинаково на всех операционных системах, на которых она работает.Ответы:
Там нет способа, который отвечает этим ограничениям
Похоже, что нет способа решить эту проблему в bash с моими ограничениями. В целом, возможные решения:
cd
,pushd
иpopd
, чтобы любая команда, которая изменяет каталоги, сначала запускала функцию ловушки. Но это может создать проблемы, потому что 1) переопределение должно быть осторожным, чтобы завершить табуляцию, как исходная команда, и вернуть тот же код завершения, и 2) если более одного инструмента используют такой подход, они не могут хорошо играть вместеtrap 'my_function
DEBUGso that every command will run the hook function. This is suboptimal because 1) it runs before every command, 2) it runs *before*
cd`, не после 3) может быть только одна функция отладки, поэтому, если другой инструмент использует этот подход, они не могут хорошо играть вместе$PROMPT_COMMAND
чтобы сначала запустить функцию ловушки. Это неоптимально, потому что это не будет работать в неинтерактивных оболочках, и потому что, если другой инструмент определяет команду приглашения, они не могут хорошо играть вместе.Короче говоря, кажется, что единственное отличное решение было бы, если бы bash предоставил что-то вроде хука zshell
chpwd_functions
, но кажется, что это невозможно смоделировать правильно.источник
Если сопровождающему не нравится, когда вы меняете определение для cd, другим вариантом будет переопределение всех команд, которые используют эту среду в каталоге:
Это было бы весьма эффективно, потому что ловушка PWD и конфигурация в каталоге будут обрабатываться только при необходимости.
В вашем примере функции check_pwd я мог бы изменить:
чтобы:
чтобы передать новый cwd (может быть более модульным, тестируемым).
источник
Установите inotify-tools в соответствии с вашим дистрибутивом.
inotifywait -emodify,create,delete -m /path/to/directory | while read line; do service httpd reload; done
В моем примере следующая команда будет перезапущена,
httpd
если что-то изменится (Изменить, Создать, Удалить) в указанном каталоге.источник