Ist es möglich, jedem Befehl in zwangsweise einen Timing-Alias hinzuzufügen (mangels einer besseren Formulierung) bash
?
Zum Beispiel möchte ich einen bestimmten Benutzer haben, der bei jeder Ausführung eines Befehls immer entweder mit date
vorher und nachher oder umbrochen wird time
.
Ist das möglich und wenn ja, wie?
preexec
, aber Sie möchten es nicht innerhalb vonpreexec
(z. B.preexec() { time $1; }
) ausführen , da die Shell es nach derpreexec
Rückkehr immer noch ausführt. Das Beste, was wir tun können, ist etwas Ähnliches.preexec()
Funktion verwenden, um das , was gerade ausgeführt wurde, tatsächlich zu verpacken , indem Sie den Befehl abrufen , ihn selbst aus der Funktion heraus ausführen und dann einen Fehler zurückgeben, damit die Shell den Befehl selbst nicht ausführt.Antworten:
Sie können die Zeit aufzeichnen, zu der eine Befehlszeile gestartet und eine Eingabeaufforderung angezeigt wird. Bash verfolgt bereits das Startdatum jeder Befehlszeile in ihrem Verlauf, und Sie können die Zeit notieren, zu der Sie die nächste Eingabeaufforderung anzeigen.
Dies gibt Ihnen nur eine zweite Auflösung und nur die Wanduhrzeit. Wenn Sie eine bessere Auflösung wünschen, müssen Sie einen externen
date
Befehl verwenden, der das%N
Format für Nanosekunden und denDEBUG
aufzurufenden Trap unterstütztdate
bevor Sie den Befehl zur Zeit ausführen.Auch mit dem
DEBUG
Falle gibt es meines Erachtens keine Möglichkeit, die Prozessorzeiten für jeden Befehl automatisch anzuzeigen oder diskriminierender zu sein als die Aufforderung zur Aufforderung.Wenn Sie bereit sind, eine andere Shell zu verwenden, erhalten Sie hier einen Zeitbericht für jeden Befehl in zsh (dies lässt sich nicht auf andere Aufgaben verallgemeinern):
Sie können einen
REPORTTIME
beliebigen ganzzahligen Wert festlegen. Die Timing-Informationen werden nur für Befehle angezeigt, die mehr als so viele Sekunden Prozessorzeit verbraucht haben.Zsh hat diese Funktion von csh übernommen, wo die Variable aufgerufen wird
time
.quelle
Ihre Optionen hier hängen von Ihrer Shell ab. Dort
zsh
gibt es eine praktische Hook-Funktionpreexec()
, die direkt vor allen interaktiven Shell-Befehlen ausgeführt wird. Durch das Erstellen einer Funktion mit diesem Namen können Sie die Ausführung von Dingen veranlassen. Sie können auch eine Funktion aufrufen,precmd()
die unmittelbar vor dem Zeichnen der nächsten Eingabeaufforderung ausgeführt wird und direkt nach Beendigung Ihres Befehls ausgeführt wird.Durch Erstellen dieses Funktionspaars können Sie beliebige Befehle ausführen lassen, bevor und nachdem Befehle an der Eingabeaufforderung ausgegeben werden. Sie können dies verwenden, um die Shell-Nutzung zu protokollieren, Sperren zu erstellen, die Umgebung zu testen oder wie in Ihrem Beispiel die Zeit oder Ressourcen zu berechnen, die während der Ausführung eines Befehls aufgewendet werden.
In diesem Beispiel erstellen wir uns einen Benchmark-Zeitstempel, bevor wir einen Befehl
preexec()
ausführen,precmd()
und berechnen dann die Zeit, die für die Ausführung des Befehls aufgewendet wurde, und geben ihn vor der Eingabeaufforderung aus oder protokollieren ihn ab. Beispiel:Hinweis: In diesem Beispiel gibt es eine noch einfachere integrierte Funktion. Alles, was Sie tun müssen, ist die Laufzeitberichterstattung in ZSH zu aktivieren, und dies wird automatisch durchgeführt.
In einer praktischeren Implementierung von
preexec()
benutze ich es, um zu sehen, ob die Shell intmux
oder läuftscreen
um Informationen über den aktuell ausgeführten Befehl zu senden, die im Registerkartennamen angezeigt werden sollen.Leider existiert dieser kleine Mechanismus in Bash nicht. Hier ist der Versuch eines Mannes, es zu replizieren . Siehe auch Gilles 'Antwort für einen ähnlichen kleinen Hack.
quelle
Der einfachste Weg wäre wahrscheinlich zu setzen
PROMPT_COMMAND
. Siehe Bash-Variablen :Um beispielsweise das Überschreiben eines vorhandenen Eingabeaufforderungsbefehls zu vermeiden, können Sie Folgendes tun:
quelle
csh
Ichtcsh
habe die beste Unterstützung für diese Funktion (und hatte sie immer).Mit anderen Worten,
set time=1
druckt die Zeit aus, die ein Befehl benötigt, der mehr als 1 Sekunde CPU-Zeit benötigt hat (System, Benutzer, verstrichen). Mit Plainset time
können Sie die Zeit für alle Befehle ausdrucken.quelle