zsh bietet einige nette Hook-Funktionen , einschließlich chpwd
zum Ausführen einer Funktion, nachdem der Benutzer die Verzeichnisse gewechselt hat.
# zsh only
function greet() { echo 'hi'; }
chpwd_functions+=("greet")
cd .. # hi
pushd # hi
popd # hi
Ich versuche das in Bash zu emulieren.
Einschränkungen:
- Es muss sowohl in interaktiven als auch in nicht interaktiven Shells funktionieren, was meiner Meinung nach bedeutet, dass es sich nicht auf so etwas verlassen kann
$PROMPT_COMMAND
- Es kann nicht neu definiert werden
cd
, da ich möchte, dass es für jeden Befehl funktioniert, der Verzeichnisse ändert (z. B.pushd
undpopd
). - Es muss nach dem Befehl des Benutzers ausgeführt werden,
trap "my_function" DEBUG
funktioniert also nicht, es sei denn, ich kann dort irgendwie sagen: "Führen Sie zuerst das, was$BASH_COMMAND
wir gefangen haben, dann auch dies aus ..." Ich sehe, dass ich das automatische Ausführen von$BASH_COMMAND
if vermeiden kann, wennextdebug
es aktiviert ist und die Trap-Funktion gibt 1 zurück, aber ich glaube nicht, dass ich erzwingen möchteextdebug
, und die Rückkehr1
für einen erfolgreichen (aber geänderten) Befehl scheint falsch.
Der letzte Teil - "Nach dem Befehl des Benutzers ausführen" - hat mich derzeit verblüfft. Wenn ich nach jedem Befehl eine Funktion ausführen kann , kann ich überprüfen lassen, ob sich das Verzeichnis seit unserer letzten Überprüfung geändert hat. Z.B:
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
}
Bin ich auf dem richtigen Weg oder gibt es einen besseren Weg? Wie kann ich einen Befehl in bash ausführen, nachdem der Benutzer die Verzeichnisse geändert hat?
cd
,pushd
undpopd
? Wie viele andere Möglichkeiten gibt es, das Verzeichnis zu wechseln?cd
grundsätzlich neu definiert.MYBIN=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )
, ändern Sie bitte nicht die vertrauenswürdigen Unix-Befehle.bash
, was auf allen Betriebssystemen, auf denen es ausgeführt wird, ziemlich gleich funktioniert.Antworten:
Es gibt keine Möglichkeit, diese Einschränkungen zu erfüllen
Es sieht so aus, als gäbe es keine Möglichkeit, dieses Problem mit meinen Einschränkungen zu lösen. Im Allgemeinen sind mögliche Lösungen:
cd
,pushd
undpopd
, so dass jeder Befehl, die Verzeichnisse ändert zuerst die Hook - Funktion ausgeführt werden . Dies kann jedoch zu Problemen führen, da 1) beim Überschreiben darauf geachtet werden muss, dass die Registerkarte wie beim ursprünglichen Befehl vollständig ausgefüllt wird und derselbe Exit-Code zurückgegeben wird, und 2) wenn mehr als ein Tool diesen Ansatz verfolgt, sie nicht gut zusammenspielen könnentrap '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`, nicht nach 3) Es kann nur eine Debug-Funktion geben. Wenn also ein anderes Tool diesen Ansatz verwendet, können sie nicht gut zusammen spielen$PROMPT_COMMAND
, um zuerst die Hook-Funktion auszuführen. Dies ist nicht optimal, da es in nicht interaktiven Shells nicht funktioniert und wenn ein anderes Tool den Eingabeaufforderungsbefehl definiert, können sie nicht gut zusammenspielen.Kurz gesagt, es scheint, als wäre die einzige gute Lösung, wenn bash so etwas wie zshells
chpwd_functions
Haken liefern würde , aber es scheint unmöglich, dies richtig zu simulieren.quelle
Wenn der Betreuer nicht möchte, dass Sie die Definition für CD ändern, können Sie auch alle Befehle neu definieren, die diese In-Directory-Umgebung verwenden:
Dies wäre sehr effizient, da der PWD-Hook und die In-Directory-Konfiguration nur bei Bedarf verarbeitet würden.
In Ihrer Beispielfunktion check_pwd könnte ich Folgendes ändern:
zu:
um das neue cwd zu übergeben (möglicherweise modularer, testbar).
quelle
Installieren Sie inotify-tools entsprechend Ihrer Distribution.
inotifywait -emodify,create,delete -m /path/to/directory | while read line; do service httpd reload; done
In meinem Beispiel wird der folgende Befehl neu
httpd
gestartet, wenn sich im angegebenen Verzeichnis etwas ändert (Ändern, Erstellen, Löschen).quelle