Ich verwende dies derzeit, um die aktuelle Uhrzeit in meiner Bash-Eingabeaufforderung anzuzeigen:
PS1=\[\e[0;32m\]\t \W>\[\e[1;37m\]
20:42:23 ~>
Ist es möglich, die seit der vorherigen Eingabeaufforderung verstrichene Zeit anzuzeigen? Sowie:
00:00:00 ~> sleep 10
00:00:10 ~> sleep 20
00:00:20 ~>
Dies hat nichts mit zu tun. Ist es möglich, die PS1 regelmäßig durch ein Skript im Hintergrund zu ändern?
Antworten:
Eine Möglichkeit wäre, die PROMPT_COMMAND-Funktion von bash zu verwenden, um Code auszuführen, der PS1 modifiziert. Die folgende Funktion ist eine aktualisierte Version meiner ursprünglichen Einreichung. Dieser verwendet zwei Umgebungsvariablen weniger und stellt ihnen "_PS1_" voran, um zu vermeiden, dass vorhandene Variablen überlastet werden.
Fügen Sie das in Ihr .bash_profile ein, um die Dinge in Gang zu bringen.
Beachten Sie, dass Sie ziemlich schnell eingeben müssen, damit der
sleep
Parameter mit dem Eingabeaufforderungsparameter übereinstimmt. Die Zeit ist wirklich der Unterschied zwischen den Eingabeaufforderungen, einschließlich der Zeit, die Sie zum Eingeben des Befehls benötigen.Späte Hinzufügung:
Basierend auf der jetzt gelöschten Antwort von @Cyrus ist hier eine Version, die die Umgebung nicht mit zusätzlichen Variablen überfüllt:
Extra späte Zugabe:
Ab Bash-Version 4.2 (
echo $BASH_VERSION
) können Sie externedate
Aufrufe mit einer neuen Zeichenfolge im printf-Format vermeiden . Ersetzen Sie die$(date +%s)
Teile durch$(printf '%(%s)T' -1)
. Ab Version 4.3 können Sie den-1
Parameter weglassen , um sich auf das Verhalten "Kein Argument bedeutet jetzt " zu verlassen.quelle
$SECONDS
, wird die Zeit seit dem Start der Shell nicht mehr verfolgt.$SECONDS
für jede Eingabeaufforderung wahrscheinlich unerwartete Verhaltensweisen hervorruft. Jede andere Shell-Funktion, die sie aus irgendeinem Grund im Zusammenhang mit der Auswertung der Laufzeit verwendet, verhält sich schlecht.Dies behandelt die Formatierung durch Berechnung. Während sie mehrmals erweitert wird, werden keine Unterschalen oder Pipes ausgeführt.
Es wird nur
$PS1
als Array behandelt und verwendet die höheren Indizes, um alle erforderlichen Zustände zwischen den Eingabeaufforderungen zu speichern / zu berechnen. Kein anderer Shell-Status ist betroffen.Ich kann es vielleicht ein wenig aufschlüsseln ...
Speichern Sie zunächst den aktuellen Wert von
$SECONDS
:Definieren Sie
$PS1[0]
als Nächstes, dass Sie selbstrekursiv sind und dabei immer die richtigen Werte festlegen,$PS1[1-3]
während Sie sich gleichzeitig selbst referenzieren. Um diesen Teil zu erhalten, müssen Sie die Reihenfolge berücksichtigen, in der Shell-Math-Ausdrücke ausgewertet werden. Am wichtigsten ist, dass Shell-Math immer die letzte Aufgabe für Shell-Math ist. Vor allem erweitert die Shell die Werte. Auf diese Weise können Sie einen alten Wert für eine Shell-Variable in einem mathematischen Ausdruck referenzieren, nachdem Sie ihn mithilfe von zugewiesen haben$
.Hier ist zunächst ein einfaches Beispiel:
Die Shell wertet diese Anweisung aus, indem sie zuerst den Wert der Stelle ersetzt, an der
$x
die$
Dollarzeichenreferenz verwendet wird. Der Ausdruck lautet also:... dann addiert die Shell 5 zum Wert von
$x
und erweitert anschließend den gesamten Ausdruck aufx+10+x
, wobei nur der tatsächlich zugewiesene Wert in der Referenzvariablen beibehalten wird. Der erweiterte Wert des mathematischen Ausdrucks ist also 40, aber der endgültige Wert von$x
ist 15.So funktioniert die
$PS1
Gleichung größtenteils auch, außer dass in den Array-Indizes eine weitere Ebene der mathematischen Erweiterung / Bewertung ausgenutzt wird.Ich bin mir nicht sicher, warum ich mich für die Verwendung
PS1[1]=!1
dort entschieden habe - ich denke, es war wahrscheinlich nur eine dumme Ästhetik -, aber dies weist 0 zu,$PS1[1]
während es für die Parametersubstitution erweitert wird. Der Wert eines bitweisen UND für 0 und alles andere ist immer 0, aber er schließt nicht wie ein Boolescher Wert kurz,&&
wenn der am weitesten links stehende Primärwert 0 ist, und daher wird der Ausdruck in Klammern jedes Mal ausgewertet. Das ist natürlich wichtig, da in dieser ersten Elipse die Anfangswerte für$PS1[2,3]
festgelegt werden.Wie auch immer,
$PS1[1]
hier ist versichert, 0 zu sein, selbst wenn es zwischen sofortigen Zügen manipuliert wird. In den Klammern steht ......
$PS1[2]
ist der Unterschied von zugewiesen$PS1[3]
und$SECONDS
, und$PS1[3]
ist der Quotient aus diesem Wert und 3600. Alle Werte werden hier initialisiert zugewiesen. Und so:... wenn es mindestens zwei Ziffern gibt,
$PS1[3]
dann ist die innere Erweiterung dort null, und weil wir wissen, dass sie$PS1[1]
0 ist,$PS1[3]
kann sie, wenn sie durch nichts ersetzt werden kann, auch$PS1[1]
auf ihren Wert erweitert werden. Auf diese Weise erweitern nur einstellige Werte für jede Iteration von$PS1[3]
Zuweisungen eine führende Null und werden$PS1[3]
unmittelbar danach modulo 60 erweitert, während gleichzeitig der nächste sukzessive kleinere Wert für jede Stunde, Minute, Sekunde zugewiesen wird.Spülen und wiederholen, bis die letzte Iteration
$PS1[3]
mit dem aktuellen Wert von überschrieben wird,$SECONDS
damit sie$SECONDS
beim nächsten Zeichnen der Eingabeaufforderung erneut verglichen werden kann .quelle
Die beste Lösung, die ich bisher gefunden habe, ist folgende: https://github.com/jichu4n/bash-command-timer
Was
[ 1s011 | May 25 15:33:44 BST ]
auch immer die verstrichene Zeit auf der rechten Seite nach dem ausgeführten Befehl druckt , damit Sie PS1 nicht überladen.Das gesamte Zeichenfolgen- und Zeitformat ist konfigurierbar. Auch die Farbe und die Präzision sind konfigurierbar. Ich weiß, dass es für einige Minimalisten da draußen ein bisschen viel sein könnte, aber es ist ziemlich cool.
quelle