Kann ich in bash veranlassen, dass eine Funktion ausgeführt wird, bevor ein Befehl ausgeführt wird?
Es gibt $PROMPT_COMMAND
einen Befehl, der ausgeführt wird, bevor eine Eingabeaufforderung angezeigt wird, dh kurz nachdem ein Befehl ausgeführt wurde.
Bashs $PROMPT_COMMAND
ist analog zu zshs precmd
Funktion; Also, was ich suche, ist eine Bash-Entsprechung zu zshs preexec
.
Beispielanwendungen: Setzen Sie Ihren Terminaltitel auf den Befehl, der ausgeführt wird. automatisch time
vor jedem Befehl hinzufügen .
command-line
bash
hook
Gilles
quelle
quelle
PS0
Variable, die sich wie eine Variable verhält,PS1
aber nach dem Lesen des Befehls, aber vor dessen Ausführung verwendet wird. Siehe gnu.org/software/bash/manual/bashref.html#Bash-VariablesAntworten:
Nicht von Haus aus, kann aber mit der
DEBUG
Falle gehackt werden . Dieser Code richtet einpreexec
undprecmd
funktioniert ähnlich wie zsh. Die Befehlszeile wird als einzelnes Argument an übergebenpreexec
.Hier ist eine vereinfachte Version des Codes zum Einrichten einer
precmd
Funktion, die vor dem Ausführen der einzelnen Befehle ausgeführt wird.Dieser Trick geht auf Glyph Lefkowitz zurück . danke an bcat für das lokalisieren des ursprünglichen autors .
Bearbeiten. Eine aktualisierte Version von Glyphs Hack finden Sie hier: https://github.com/rcaloras/bash-preexec
quelle
"$BASH_COMMAND" = "$PROMPT_COMMAND"
Vergleich funktioniert bei mir nicht i.imgur.com/blneCdQ.pngtime for i in {1..10}; do true; done
dauert normalerweise 0,040 Sekunden und 1.400 bis 1.600 Sekunden, nachdem die DEBUG-Falle aktiviert wurde. Dadurch wird der Trap-Befehl zweimal pro Schleife ausgeführt - und bei Cygwin ist das zum Ausführen von sed erforderliche Gabeln mit ungefähr 0,030 Sekunden für das alleinige Gabeln (Geschwindigkeitsdifferenz zwischenecho
eingebautem und/bin/echo
) unerschwinglich langsam . Vielleicht etwas, an das man denken sollte.PROMPT_COMMAND
Variable (zB begrenzt durch;
), müssen Sie möglicherweise Musterabgleich in der zweiten Zeile der verwendenpreexec_invoke_exec
Funktion, wie folgt aus :[[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]]
. Dies liegt daranBASH_COMMAND
, dass jeder der Befehle separat dargestellt wird.Sie können den
trap
Befehl (vonhelp trap
) verwenden:Um beispielsweise den Terminaltitel dynamisch zu ändern, können Sie Folgendes verwenden:
Aus dieser Quelle.
quelle
help trap
heißt es "Wenn ein SIGNAL_SPEC DEBUG ist, wird ARG nach jedem einfachen Befehl ausgeführt".trap '[ -n "$COMP_LINE" ] && [ "$BASH_COMMAND" != "$PROMPT_COMMAND" ] && date "+%X";echo -e "\e]0;$BASH_COMMAND\007"' DEBUG
. Dadurch wird der Befehl in den Titel eingefügt und die aktuelle Zeit direkt vor jedem Befehl gedruckt, dies geschieht jedoch nicht bei der Ausführung$PROMPT_COMMAND
.[ -z "$COMP_LINE" ]
.Es ist keine Shell-Funktion, die ausgeführt wird, aber ich habe eine
$PS0
Eingabeaufforderung eingegeben, die angezeigt wird, bevor ein Befehl ausgeführt wird. Details hier: http://stromberg.dnsalias.org/~strombrg/PS0-prompt/$PS0
ist inbash
4.4 enthalten, obwohl es eine Weile dauern wird, bis die meisten Linux-Versionen 4.4 enthalten - Sie können jedoch auch selbst 4.4 erstellen. in diesem Fall sollten Sie es wahrscheinlich unterlegen/usr/local
, hinzufügen/etc/shells
und hinzufügenchsh
. Dann loggen Sie sich aus und wieder ein, vielleicht als Testssh
für sich selbst @ localhost odersu
für sich selbst.quelle
Ich musste vor kurzem genau dieses Problem für ein Nebenprojekt von mir lösen. Ich habe eine ziemlich robuste und ausfallsichere Lösung erstellt, die die Preexec- und Precmd-Funktionalität von zsh für bash emuliert.
https://github.com/rcaloras/bash-preexec
Es basierte ursprünglich auf der Lösung von Glyph Lefkowitz, aber ich habe es verbessert und auf den neuesten Stand gebracht. Gerne helfen wir Ihnen weiter oder fügen bei Bedarf eine Funktion hinzu.
quelle
Danke für die Hinweise! Am Ende habe ich Folgendes verwendet:
Genießen!
quelle
Ich habe eine Methode geschrieben, um alle 'bash'-Befehle / eingebauten Befehle in eine Textdatei oder einen' syslog'-Server zu schreiben, ohne einen Patch oder ein spezielles ausführbares Tool zu verwenden.
Die Bereitstellung ist sehr einfach, da es sich um ein einfaches Shellscript handelt, das bei der Initialisierung der 'Bash' einmal aufgerufen werden muss.
Siehe die Methode hier .
quelle