it-swarm.com.de

Bash-Skript zur Berechnung der verstrichenen Zeit

Ich schreibe ein Skript in Bash, um die für die Ausführung meiner Befehle verstrichene Zeit zu berechnen.

STARTTIME=$(date +%s)
#command block that takes time to complete...
#........
ENDTIME=$(date +%s)
echo "It takes $($ENDTIME - $STARTTIME) seconds to complete this task..."

Ich denke, meine Logik ist korrekt, aber am Ende erhalte ich den folgenden Ausdruck:

"Es dauert Sekunden, um diese Aufgabe abzuschließen ..."

Stimmt etwas mit meiner Saitenbewertung nicht?

Ich glaube, Bash-Variablen sind untypisiert, ich würde es lieben, wenn es in Bash dennoch eine "String to Integer" -Methode gibt.

98
Michael Mao

Entweder $(()) oder $[] Dient zur Berechnung des Ergebnisses einer arithmetischen Operation. Sie verwenden $(), wobei der String einfach als Befehl ausgewertet wird. Es ist ein subtiler Unterschied. Hoffe das hilft.

Wie in den Kommentaren zu dieser Antwort erwähnt, ist $[] Veraltet und $(()) sollte bevorzugt werden.

72

Ich finde es sehr sauber, die interne Variable "$ SECONDS" zu verwenden

SECONDS=0 ; sleep 10 ; echo $SECONDS

123
Lon Kaut

Sie versuchen, die Nummer in ENDTIME als Befehl auszuführen. Sie sollten auch einen Fehler wie 1370306857: command not found Sehen. Verwenden Sie stattdessen die arithmetische Erweiterung :

echo "It takes $(($ENDTIME - $STARTTIME)) seconds to complete this task..."

Sie können die Befehle auch in einem separaten Skript (commands.sh) Speichern und den Befehl time verwenden:

time commands.sh
49
perreal

Sie können hier das Schlüsselwort time von Bash mit einer entsprechenden Formatzeichenfolge verwenden

TIMEFORMAT='It takes %R seconds to complete this task...'
time {
    #command block that takes time to complete...
    #........
 }

Hier ist, was die Referenz sagt über TIMEFORMAT :

Der Wert dieses Parameters wird als Formatzeichenfolge verwendet, die angibt, wie die Zeitinformationen für Pipelines, denen das reservierte Wort time vorangestellt ist, angezeigt werden sollen. Das '% ’Zeichen führt eine Escape-Sequenz ein, die auf einen Zeitwert oder eine andere Information erweitert wird. Die Escape-Sequenzen und ihre Bedeutungen lauten wie folgt: Die geschweiften Klammern bezeichnen optionale Teile.

%%

    A literal ‘%’.
%[p][l]R

    The elapsed time in seconds.
%[p][l]U

    The number of CPU seconds spent in user mode.
%[p][l]S

    The number of CPU seconds spent in system mode.
%P

    The CPU percentage, computed as (%U + %S) / %R. 

Das optionale p ist eine Ziffer, die die Genauigkeit und die Anzahl der Nachkommastellen angibt. Ein Wert von 0 bewirkt, dass kein Dezimalpunkt oder Bruch ausgegeben wird. Maximal drei Nachkommastellen dürfen angegeben werden; Werte von p größer als 3 werden in 3 geändert. Wenn p ist nicht angegeben, wird der Wert 3 verwendet.

Das optionale l gibt ein längeres Format einschließlich Minuten in der Form MMmSS.FFs an. Der Wert von p bestimmt, ob der Bruch enthalten ist oder nicht.

Wenn diese Variable nicht gesetzt ist, verhält sich Bash so, als hätte sie den Wert

$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'

Wenn der Wert null ist, werden keine Zeitinformationen angezeigt. Eine abschließende neue Zeile wird hinzugefügt, wenn die Formatzeichenfolge angezeigt wird.

24
gniourf_gniourf

Versuchen Sie den folgenden Code:

start=$(date +'%s') && sleep 5 && echo "It took $(($(date +'%s') - $start)) seconds"
6
Bulmaro Herrera

versuchen Sie, die Zeit mit der Option "Verstrichene Sekunden" zu verwenden:

/usr/bin/time -f%e sleep 1 unter Bash.

oder \time -f%e sleep 1 in interaktiver Bash.

siehe die Zeitmanpage:

Benutzer der Bash-Shell müssen einen expliziten Pfad verwenden, um den externen Zeitbefehl und nicht die in der Shell integrierte Variante auszuführen. Auf Systemen, auf denen time in/usr/bin installiert ist, würde das erste Beispiel zu/usr/bin/time wc/etc/hosts

und

FORMATTING THE OUTPUT
...
    %      A literal '%'.
    e      Elapsed  real  (wall  clock) time used by the process, in
                 seconds.
2
Lynch

Bei größeren Zahlen möchten wir möglicherweise in einem besser lesbaren Format drucken. Das folgende Beispiel verhält sich wie das andere, druckt jedoch auch im "menschlichen" Format:

secs_to_human() {
    if [[ -z ${1} || ${1} -lt 60 ]] ;then
        min=0 ; secs="${1}"
    else
        time_mins=$(echo "scale=2; ${1}/60" | bc)
        min=$(echo ${time_mins} | cut -d'.' -f1)
        secs="0.$(echo ${time_mins} | cut -d'.' -f2)"
        secs=$(echo ${secs}*60|bc|awk '{print int($1+0.5)}')
    fi
    echo "Time Elapsed : ${min} minutes and ${secs} seconds."
}

Einfaches Testen:

secs_to_human "300"
secs_to_human "305"
secs_to_human "59"
secs_to_human "60"
secs_to_human "660"
secs_to_human "3000"

Ausgabe:

Time Elapsed : 5 minutes and 0 seconds.
Time Elapsed : 5 minutes and 5 seconds.
Time Elapsed : 0 minutes and 59 seconds.
Time Elapsed : 1 minutes and 0 seconds.
Time Elapsed : 11 minutes and 0 seconds.
Time Elapsed : 50 minutes and 0 seconds.

Verwendung in einem Skript wie in anderen Beiträgen beschrieben (Startpunkt erfassen, dann Funktion mit Endzeit aufrufen:

start=$(date +%s)
# << performs some task here >>
secs_to_mins_and_secs "$(($(date +%s) - ${start}))"
0
Mike Q