uptime im sh script

@FreeBSDuser:
Stimmt, das ist totalemente falsch und es wird tatsächlich nur die aktuelle Uhrzeit aus der Uptime in Minuten umgerechnet. *boing*

@Brusko:
Die Uptime in Minuten per "uptime" abzuleiten, das lass' ich besser mal sein, weil, je nachdem ob Minuten, Stunden oder Tage verstrichen sind, die erst mal unterschiedlich geparst werden muss. Deshalb hefte ich mich an die Fährte von laemodost mit 'sysctrl' als Basis und löse die Aufgabe noch mal mit sed (besser nach Tutorials suchen) und dc (man 1 dc):

Code:
sysctl -n kern.boottime | sed -E 's/[^0-9]*([0-9]+).*/'`date '+%s'`' \1 - 60 \/ p/' | dc

dc (Taschenrechner arbeitet in umgekehrter polnischer Notation: Argumente werden erst auf einen Stack gelegt und dann durch die Anwendung des darauf folgenden Operators mit dem Ergebnis substituiert; mit 'p' wird das oberste Element des Stacks ausgegeben - in dem Fall das Endergebnis) bekommt die Rechnung

'aktuelle_Zeit_in_Sekunden kern_boot_time_in_Sekunden - 60 / p'

zugeführt, macht also des selbe was Kollege laemodost vorschlägt.

sysctl liefert die Eingabe für sed
Code:
{ sec = 1231721314, usec = 549041 } Mon Jan 12 01:48:34 2009

sed schneidet die Boottime aus und erzeugt die Rechnung für dc wie folgt (ich versuch's mal kurz und bündig darzulegen):

Grundsätzlich ersetzt sed in einer Eingabe alle gefundenen MUSTER durch eine ZEICHENKETTE mit folgendem sed-Steuerstring:

's/MUSTER/ZEICHENKETTE/'

In dem Fall sollen aber nicht nur Teile der Eingabe durch andere Zeichen ausgetauscht werden, sondern die gesamte Eingabe muss ersetzt werden durch eine komplett andere ZEICHENKETTE. Aus dem Grund muss das MUSTER so gestaltet werden, dass es die komplette Eingabe erfasst. Und das macht es

Code:
[^0-9]*([0-9]+).*

indem von der Eingabe zuerst alles entgegen genommen wird was keine Zahl ist

[^0-9]*
mit [0-9] == alle Zeichen von 0 bis 9; [^0-9] == NICHT alle Zeichen von 0-9; '*' == die zuvor definierten Zeichen keinmal oder mehrmals erfassen.

Als nächstes wird die erste Zahl entgegen genommern

[0-9]+
mit + == die zuvor definierten Zeichen mindestens einmal oder mehrmals erfassen.

Abschließend wird der Rest der Eingabe entgegen genommen

.*
mit '.' == ein beliebiges Zeichen.

Würde der sed-Steuerstring als ZEICHENKETTE die leere Zeichenkette ('s/MUSTER//') enthalten, sed würde als Ergebnis einen leeren String zurückgegeben. Aber das wollen wir ja nicht. Deshalb definiert die ZEICHENKETTE, das MUSTER soll ersetzt werden durch

zuerst die Uptime in Sekunden. Jene wird mit `date '+%s'` berechnet und zum restlichen sed-Steuerstring zusammengesetzt. Somit enthält also ZEICHENKETTE die aktuelle Zeit in Sekunden als erste Zahl.

Dann wird die erste im Muster erkannte und zur Referenzierung mit '\1' durch Klammern markierte Zeichenfolge der ZEICHENKETTE hinzugefügt.

Abschließend werden die restlichen Anweisungen für dc erzeugt womit die ZEICHENKETTE nun vollständig ist.

sed hat jetzt alle Angaben damit dc die Uptime in Sekunden berechnen kann.

---

sed muss in dem Fall mit '-E' in den Modus "erweiterte reguläre Audrücke" umgeschaltete werden, damit er mit markierten Mustern '()' und deren Referenzierung '\1' hantieren kann.

Die Angabe von MUSTER und ZEICHENKETTE im sed-Steuerstring muss nicht unbedingt durch '/' getrennt werden. Es kann im Prinzip ein beliebiges Zeichen wie z.B. '#' verwendet werden, was das Hantieren mit Sonderzeichen in MUSTER und ZEICHENKETTE vereinfacht ohne diese mit Backslash entwerten zu müssen.

In dem Fall kann also vereinfachend geschrieben werden:

Code:
sysctl -n kern.boottime | sed -E 's#[^0-9]*([0-9]+).*#'`date '+%s'`' \1 - 60 / p#' | dc

---

So funktioniert das. Schritt für Schritt kommt man den Möglichkeiten von sed wie erwähnt am besten mit entsprechenden Tutorials auf die Spur und kann dann immer noch 'man 1 sed' lesen.

Die sed-Kiste mit erweiterten regulären Ausdrücken (-E) ist sehr mächtig und der sed-Steuerstring kann grundsätzlich auch z.B. in Perl und php (preq_match / preq_replace) verwendet werden. Somit lohnt sich die Einarbeitung.
 
Zuletzt bearbeitet:
Mal eine Frage, warum benutzt eigentlich keiner eine der uptimes aus "kern.timecounter"? Der OP musste ja dann nur in einem "if" das Script abrechen, wenn diese umgerechnet > 24h ist.
 
Nun wenn du mir denn sagen könntest welche Zahl das denn von den Counters ist , hab da einige mal umgerechnet kam aber nir auf sekunden oder so.z.b die nmircotime
 
Zurück
Oben