PS1[3]=$SECONDS
PS1='${PS1[!(PS1[1]=!1&(PS1[3]=(PS1[2]=$SECONDS-${PS1[3]})/3600))
]#${PS1[3]%%*??}0}$((PS1[3]=(PS1[2]/60%60), ${PS1[3]})):${PS1[1
]#${PS1[3]%%*??}0}$((PS1[3]=(PS1[2]%60), ${PS1[3]})):${PS1[1
]#${PS1[3]%%*??}0}$((PS1[3]=(SECONDS), ${PS1[3]})):'$PS1
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.
00:00:46:[mikeserv@desktop tmp]$
00:00:01:[mikeserv@desktop tmp]$
00:00:00:[mikeserv@desktop tmp]$
00:00:01:[mikeserv@desktop tmp]$
00:00:43:[mikeserv@desktop tmp]$ sleep 10
00:00:33:[mikeserv@desktop tmp]$ sleep 10
00:00:15:[mikeserv@desktop tmp]$
00:00:15:[mikeserv@desktop tmp]$
00:00:02:[mikeserv@desktop tmp]$
00:02:27:[mikeserv@desktop tmp]$
Ich kann es vielleicht ein wenig aufschlüsseln ...
Speichern Sie zunächst den aktuellen Wert von $SECONDS
:
PS1[3]=$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:
x=10; echo "$(((x+=5)+$x+x))" "$x"
40 15
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:
(x+=5)+10+x
... dann addiert die Shell 5 zum Wert von $x
und erweitert anschließend den gesamten Ausdruck auf x+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.
PS1='${PS1[!(PS1[1]=!1&(...))]#...}...'
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[3]=(PS1[2]=$SECONDS-${PS1[3]})/3600
... $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:
${PS1[1]#${PS1[3]%%*??}0}
... 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 .