Ich möchte herausfinden, wie lange eine Operation in einem Linux-Shell-Skript dauert. Wie kann ich das machen?
74
Es ist eine gute Idee, den Befehl time zu verwenden, wie andere vorgeschlagen haben.
Eine weitere Option ist die Verwendung der in Magic integrierten Variablen $ SECONDS, die die Anzahl der Sekunden seit Beginn der Skriptausführung enthält. Sie können sagen:
START_TIME=$SECONDS
dosomething
ELAPSED_TIME=$(($SECONDS - $START_TIME))
Ich denke, das ist Bash-spezifisch, aber da Sie unter Linux arbeiten, gehe ich davon aus, dass Sie Bash verwenden.
SECONDS
hat sie keine besonderen Eigenschaften mehr) Bedeutung). Siehe POSIX spec @ pubs.opengroup.org/onlinepubs/9699919799/basedefs/… , Reservieren von Kleinbuchstaben für die Verwendung durch Anwendungen. Beachten Sie dabei , dass Shell- und Umgebungsvariablen einen einzigen Namespace verwenden. - Der Namensraum von Umgebungsvariablennamen mit Kleinbuchstaben ist reserviert für Anwendungen.Verwenden Sie den
time
Befehl.time ls /bin
.quelle
time
ist nicht geeignet, wenn Sie komplexe Befehlssequenztime (ls / ; sleep 2; ls /bin)
.\
und()
es wurde komplexer./usr/bin/time -f '%C => %E' (ls / ; sleep 2; ls /bin)
Würfebash: syntax error near unexpected token '('
Versuchen Sie folgendes Beispiel:
START_TIME=$SECONDS # do something sleep 65 ELAPSED_TIME=$(($SECONDS - $START_TIME)) echo "$(($ELAPSED_TIME/60)) min $(($ELAPSED_TIME%60)) sec" #> 1 min 5 sec
quelle
Viele der Antworten erwähnen
$SECONDS
, aber diese Variable ist sogar noch besser als sie denken :Dies bedeutet, dass Sie diese Variable einfach direkt am Ende Ihres Skripts abfragen können, um die verstrichene Zeit zu drucken:
#!/usr/bin/env bash # Do stuff... echo "Script finished in $SECONDS seconds."
Sie können auch kleinere Abschnitte wie folgt zeitlich festlegen:
#!/usr/bin/env bash # Do stuff SECONDS=0 # Do timed stuff... echo "Timed stuff finished in $SECONDS seconds."
quelle
Hier ist das Skript, um die verstrichene Zeit in Millisekunden zu ermitteln. Ersetzen Sie die Zeile sleep 60 durch den Code, den Sie ausführen möchten.
a=0 while [ $a -lt 10 ] do START_TIME=`echo $(($(date +%s%N)/1000000))` sleep 3 END_TIME=`echo $(($(date +%s%N)/1000000))` ELAPSED_TIME=$(($END_TIME - $START_TIME)) echo $ELAPSED_TIME if [ $a -eq 10 ] then break fi a=`expr $a + 1` done
quelle
Nur um jemandem wie mir zu helfen, der einen Fehler erhält:
arithmetic expression: expecting primary: "-"
Überprüfen Sie Ihr Shellscript, das beginnen soll mit:
#!/bin/bash
Prost!
quelle
GNU
time
Ich habe auch großen Spaß mit dem GNU-
time
Befehl: https://www.gnu.org/software/time/, der im Vergleich zum integriertentime
Bash einige wichtige Optionen bietet .Beispielnutzung:
env time --format '%e' --output time.log sleep 1
Ausgabe:
Erläuterung:
env
:/usr/bin/time
anstelle des eingebauten Bash zu finden--format '%e'
: Druckzeit in Sekunden, sieheman time
.Dies ist oft das, was ich beim Benchmarking möchte: eine einzelne Zahl anstelle von Minuten + Sekunden.
Und ein wichtiges Muster, das ich oft benutze, ist:
bench-cmd() ( logfile=time.log echo "cmd $@" >> "$logfile" printf 'time ' >> "$logfile" bench_cmd="env time --append --format '%e' --output '$logfile' $@" eval "$bench_cmd" echo >> "$logfile" ) rm -f time.log bench-cmd sleep 1 bench-cmd sleep 2 bench-cmd sleep 3 cat time.log
GitHub stromaufwärts .
Ausgabe:
Erläuterung:
--output
: Gibt die Zeit in eine Datei aus.Standardmäßig geht die Ausgabe an stderr, daher ist diese Option wichtig, um das Timing vom stderr des Befehls zu trennen.
--append
: an die Datei anhängen anstatt zu überschreiben.Dadurch kann ich die gesamte Benchmark-Ausgabe in einer einzigen Datei konzentrieren.
quelle