zsh zapewnia pewne ładny funkcje przechwytujące , w tym chpwd
na prowadzenie funkcji, gdy użytkownik zmienia katalogów.
# zsh only
function greet() { echo 'hi'; }
chpwd_functions+=("greet")
cd .. # hi
pushd # hi
popd # hi
Staram się to naśladować.
Ograniczenia:
- Musi działać zarówno w interaktywnych, jak i nieinteraktywnych powłokach, co moim zdaniem oznacza, że nie może polegać na czymś takim
$PROMPT_COMMAND
- Nie można przedefiniować
cd
, ponieważ chcę, aby działał dla każdego polecenia zmieniającego katalogi (np.pushd
Ipopd
) - Musi działać po komendzie użytkownika, więc
trap "my_function" DEBUG
nie działa, chyba że mogę w jakiś sposób powiedzieć: „najpierw uruchom$BASH_COMMAND
pułapkę, a następnie również zrób to ...”. Widzę, że mogę uniknąć automatycznego uruchamiania,$BASH_COMMAND
jeśliextdebug
włączono a funkcja pułapki zwraca 1, ale nie sądzę, że chcę wymusićextdebug
, a powrót1
do udanej (ale zmodyfikowanej) komendy wydaje się niewłaściwy.
Ostatnia część - „biegnij za poleceniem użytkownika” - jest tym, co mnie obecnie zaskoczyło. Gdybym można uruchomić funkcję po każdym poleceniu, może mam to sprawdzić, czy katalog został zmieniony od ostatniego sprawdzenia. Na przykład:
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
}
Czy jestem na dobrej drodze, czy jest lepszy sposób? Jak mogę uruchomić polecenie w bash po tym, jak użytkownik zmieni katalogi?
cd
,pushd
ipopd
? Ile jest innych sposobów zmiany katalogu?cd
.MYBIN=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )
Proszę nie zmieniać zaufanych poleceń Uniksa.bash
, który działa prawie tak samo na wszystkich systemach operacyjnych, na których działa.Odpowiedzi:
Nie ma sposobu, aby sprostać tym ograniczeniom
Wygląda na to, że nie ma sposobu na rozwiązanie tego problemu przez bash z moimi ograniczeniami. Ogólnie możliwe rozwiązania to:
cd
,pushd
ipopd
, tak, że każde polecenie, które zmienia katalogów spowoduje uruchomienie funkcji haka. Może to jednak powodować problemy, ponieważ 1) przesłonięcie musi być ostrożne, aby uzupełnić tabulator jak oryginalne polecenie i zwrócić ten sam kod wyjścia oraz 2) jeśli więcej niż jedno narzędzie przyjmuje takie podejście, nie mogą grać dobrze razemtrap '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`, nie po 3) może istnieć tylko jedna funkcja debugowania, więc jeśli inne narzędzie korzysta z tego podejścia, nie mogą grać dobrze razem$PROMPT_COMMAND
aby najpierw uruchomić funkcję zaczepu. Jest to nieoptymalne, ponieważ nie będzie działać w nieinteraktywnych powłokach, a ponieważ jeśli inne narzędzie zdefiniuje polecenie, nie będzie mogło grać dobrze razem.Krótko mówiąc, wydaje się, że jedynym świetnym rozwiązaniem byłoby, gdyby bash dostarczył coś podobnego do
chpwd_functions
haka Zshell , ale nie można poprawnie go zasymulować.źródło
Jeśli opiekun nie lubi zmiany definicji cd, inną opcją byłoby ponowne zdefiniowanie wszystkich poleceń korzystających z tego środowiska w katalogu:
Byłoby to dość wydajne, ponieważ hak PWD i konfiguracja w katalogu byłyby przetwarzane tylko w razie potrzeby.
W twojej przykładowej funkcji check_pwd mogę zmienić:
do:
w celu przekazania nowego cwd (może być bardziej modułowy, testowalny).
źródło
Zainstaluj narzędzia inotify zgodnie z dystrybucją.
inotifywait -emodify,create,delete -m /path/to/directory | while read line; do service httpd reload; done
W moim przykładzie następujące polecenie zostanie ponownie uruchomione,
httpd
jeśli cokolwiek się zmieni (Modyfikuj, Utwórz, Usuń) w określonym katalogu.źródło