Ich möchte herausfinden, wie lange eine Operation in einem Linux-Shell-Skript dauert. Wie kann ich das machen?
Ich möchte herausfinden, wie lange eine Operation in einem Linux-Shell-Skript dauert. Wie kann ich das machen?
Antworten:
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.
Verwenden Sie den time
Befehl. time ls /bin
.
time
ist nicht geeignet, wenn Sie komplexe Befehlssequenz
time (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
Viele der Antworten erwähnen $SECONDS
, aber diese Variable ist sogar noch besser als sie denken :
Durch die Zuweisung zu dieser Variablen wird die Anzahl auf den zugewiesenen Wert zurückgesetzt, und der erweiterte Wert wird zum zugewiesenen Wert plus der Anzahl der Sekunden seit der Zuweisung.
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."
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
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!
GNU time
Ich habe auch großen Spaß mit dem GNU- time
Befehl: https://www.gnu.org/software/time/, der im Vergleich zum integrierten time
Bash einige wichtige Optionen bietet .
Beispielnutzung:
env time --format '%e' --output time.log sleep 1
Ausgabe:
1.00
Erläuterung:
env
: /usr/bin/time
anstelle des eingebauten Bash zu finden
--format '%e'
: Druckzeit in Sekunden, siehe man 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
Ausgabe:
cmd sleep 1
time 1.00
cmd sleep 2
time 2.00
cmd sleep 3
time 3.00
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.
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.