Ich möchte etwas in einer Linux-Shell unter einigen verschiedenen Bedingungen ausführen und die Ausführungszeit jeder Ausführung ausgeben können.
Ich weiß, ich könnte ein Perl- oder Python-Skript schreiben, das dies tun würde, aber gibt es eine Möglichkeit, dies in der Shell zu tun? (was zufällig bash ist)
Verwenden Sie das integrierte time
-Schlüsselwort:
$ help time time: time [-p] PIPELINE Führen Sie PIPELINE aus und drucken Sie eine Zusammenfassung der Echtzeit, der CPU-Zeit des Benutzers und und System-CPU-Zeit, die für die Ausführung von PIPELINE aufgewendet wurde, wenn sie beendet wird . Der Rückgabestatus ist der Rückgabestatus von PIPELINE. Die -p-Option druckt die Timing-Zusammenfassung in einem etwas anderen Format. Dies verwendet der Wert der TIMEFORMAT-Variablen als Ausgabeformat .
Beispiel:
$ time sleep 2
real 0m2.009s benutzer 0m0.000s sys 0m0.004s
Sie können weitaus detailliertere Informationen erhalten als die in time
(von Robert Gamble erwähnte) bash-integrierte Verwendung von time (1) . Normalerweise ist dies /usr/bin/time
.
Anmerkung des Editors: Um sicherzustellen, dass Sie das external-Dienstprogrammtime
anstelle des time
-Schlüsselworts Ihrer Shell aufrufen, rufen Sie es als /usr/bin/time
auf.time
ist ein Dienstprogramm mit POSIX-Mandat , die einzige unterstützte Option ist jedoch -p
.
Spezifische Plattformen implementieren spezifische, nicht standardmäßige Erweiterungen: -v
arbeitet mit dem time
-Dienstprogramm von GNU, wie unten gezeigt (die Frage wird mit linux markiert); Die BSD/macOS-Implementierung verwendet -l
zur Erstellung einer ähnlichen Ausgabe - siehe man 1 time
.
Beispiel für eine ausführliche Ausgabe:
$ /usr/bin/time -v sleep 1
Command being timed: "sleep 1"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 1%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 0
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 210
Voluntary context switches: 2
Involuntary context switches: 1
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
#!/bin/bash
START=$(date +%s)
# do something
# start your script work here
ls -R /etc > /tmp/x
rm -f /tmp/x
# your logic ends here
END=$(date +%s)
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"
Versuchen Sie für eine zeilenweise Delta-Messung gnomon .
Ein Kommandozeilen-Dienstprogramm, ein bisschen wie moreutils 's, um der Standardausgabe eines anderen Befehls Zeitstempelinformationen voranzustellen. Nützlich für lang laufende Prozesse, bei denen Sie eine historische Aufzeichnung dessen wünschen, was so lange dauert.
Sie können auch die Optionen --high
und/oder --medium
verwenden, um eine Längenschwelle in Sekunden anzugeben, über die gnomon den Zeitstempel in rot oder gelb hervorhebt. Und Sie können auch ein paar andere Dinge tun.
Wenn Sie mehr Genauigkeit wünschen, verwenden Sie %N
mit date
(und verwenden Sie bc
für den Diff, da $(())
nur Ganzzahlen behandelt).
So geht's:
start=$(date +%s.%N)
# do some stuff here
dur=$(echo "$(date +%s.%N) - $start" | bc)
printf "Execution time: %.6f seconds" $dur
Beispiel:
start=$(date +%s.%N); \
sleep 0.1s; \
dur=$(echo "$(date +%s.%N) - $start" | bc); \
printf "Execution time: %.6f seconds\n" $dur
Ergebnis:
Execution time: 0.104623 seconds
Wenn Sie die Zeiten später für die Berechnung verwenden möchten, erfahren Sie, wie Sie mit der -f
-Option von /usr/bin/time
code ausgeben, um Zeit zu sparen. Hier ist ein Code, den ich kürzlich verwendet habe, um die Ausführungszeiten einer ganzen Klasse von Schülerprogrammen zu ermitteln und zu sortieren:
fmt="run { date = '$(date)', user = '$who', test = '$test', Host = '$(hostname)', times = { user = %U, system = %S, elapsed = %e } }"
/usr/bin/time -f "$fmt" -o $timefile command args...
Ich habe später alle $timefile
-Dateien verkettet und die Ausgabe in einen Lua-Interpreter geleitet. Sie können dasselbe mit Python oder Bash oder was auch immer Ihre Lieblingssyntax ist. Ich liebe diese Technik.
Wenn Sie nur Sekundengenauigkeit benötigen, können Sie die eingebaute Variable $SECONDS
verwenden, die die Anzahl Sekunden angibt, die die Shell ausgeführt hat.
while true; do
start=$SECONDS
some_long_running_command
duration=$(( SECONDS - start ))
echo "This run took $duration seconds"
if some_condition; then break; fi
done
Sie können time
und subshell ()
verwenden:
time (
for (( i=1; i<10000; i++ )); do
echo 1 >/dev/null
done
)
Oder in derselben Shell {}
:
time {
for (( i=1; i<10000; i++ )); do
echo 1 >/dev/null
done
}
Der Weg ist
$ > g++ -lpthread perform.c -o per
$ > time ./per
ausgabe ist >>
real 0m0.014s
user 0m0.010s
sys 0m0.002s
eine möglicherweise einfache Methode (die möglicherweise nicht den unterschiedlichen Anforderungen der Benutzer entspricht) ist die Verwendung von Shell Prompt.it ist eine einfache Lösung, die in einigen Fällen nützlich sein kann. Sie können die Bash-Aufforderungsfunktion wie im folgenden Beispiel verwenden:
exportiere PS1 = '[\ t\u @\h]\$'
Der obige Befehl führt zur Änderung der Shell-Eingabeaufforderung in:
[HH: MM: SS-Benutzername @ Hostname] $
Jedes Mal, wenn Sie einen Befehl ausführen (oder die Eingabetaste drücken) und zur Shell-Eingabeaufforderung zurückkehren, wird in der Eingabeaufforderung die aktuelle Uhrzeit angezeigt.
Anmerkungen:
1) Beachten Sie, dass, wenn Sie einige Zeit gewartet haben, bevor Sie den nächsten Befehl eingeben, diese Zeit berücksichtigt werden muss, dh, die in der Shell-Eingabeaufforderung angezeigte Zeit ist der Zeitstempel, zu dem die Shell-Eingabeaufforderung angezeigt wurde, nicht Wenn Sie den Befehl eingeben. Einige Benutzer wählen die Eingabetaste, um eine neue Aufforderung mit einem neuen Zeitstempel zu erhalten, bevor sie für den nächsten Befehl bereit sind.
2) Es gibt andere verfügbare Optionen und Modifizierer, die zum Ändern der Bash-Eingabeaufforderung verwendet werden können. Weitere Informationen finden Sie unter (Man Bash).