Linux / Befehl time: Befehlsausführungszeit messen

time misst die verstrichene Zeit und die CPU-Zeit für einen Befehl oder eine Pipeline. Das time-Schlüsselwort in Bash kann eingebaute Shell-Befehle, Funktionen und Pipelines messen, während das externe GNU /usr/bin/time detaillierte Ressourcennutzung wie Speicher und I/O bereitstellen kann.

Für einfache Geschwindigkeitsprüfungen ist Bash time praktisch, und wenn Sie Statistiken auf Betriebssystemebene wie maximalen Speicher und Seitenfehler benötigen, ist es besser, explizit das externe time auszuführen.

Ergänzende Befehle und Anwendungsfälle finden Sie in Liste der häufig verwendeten Befehle in Linux.

Was ist der time-Befehl?

In Bash ist time ein Schlüsselwort, das als Syntax vor gewöhnlichen ausführbaren Dateien erkannt wird. Da es ein Schlüsselwort ist, kann es natürlich nicht nur ein einzelnes externes Programm messen, sondern auch ganze Pipelines, Shell-Funktionen und eingebaute Befehle.

Viele Linux-Systeme haben auch das GNU Time-Programm separat installiert. Obwohl es denselben Namen trägt, sind die Optionen und Ausgabeinformationen unterschiedlich, daher sollten Sie Ihre aktuelle Umgebung mit folgendem Befehl überprüfen.

type -a time
command -V time
ls -l /usr/bin/time

Grundsyntax von Bash time

time [-p] command [arguments...]
time [-p] command1 | command2

Setzen Sie time vor den Befehl, den Sie messen möchten.

time sleep 1
time find /usr -type f >/dev/null

Wenn der Befehl abgeschlossen ist, werden normalerweise drei Werte angezeigt: real, user und sys.

Die Bedeutung von real, user, sys

Artikel Bedeutung
real Die tatsächlich vergangene Zeit von Start bis Ende. Sie umfasst auch die Zeit, die durch Warten aufgrund von Festplatte, Netzwerkverzögerungen und anderen Prozessen verbracht wurde.
user Die kumulative Zeit, die der Prozess im Benutzermodus der CPU verwendet hat.
sys Die kumulative CPU-Zeit, die im Kernel-Modus für den Prozess verwendet wird.

Wenn mehrere Kerne oder Prozesse parallel verwendet werden, kann user + sys größer sein als real. Umgekehrt kann, wenn die I/O-Wartezeit lang ist, real groß sein, während die CPU-Zeit klein ist.

Das gesamte Pipeline messen

Das reservierte Bash-Wort time misst, bis die gesamte folgende Pipeline abgeschlossen ist.

time find /var/log -type f -print0 | xargs -0 wc -l >/dev/null

Wenn Sie nur den ersten Befehl einer Pipeline separat messen möchten, müssen Sie Gruppen klar organisieren oder beim Messen mit externen Werkzeugen auf den Messbereich achten. Es ist wichtig, zuerst die Start- und Endpunkte der Aufgabe zu bestimmen, die Sie messen möchten.

Mehrere Befehle als eine einzelne Aufgabe messen

Indem Sie eine Liste von Befehlen mit geschweiften Klammern oder einer Unter-Shell gruppieren, können Sie die Gesamtzeit messen.

time {
  make clean
  make -j4
}
time (
  cd /srv/app
  ./build.sh
)

Eine Gruppe mit geschweiften Klammern { ...; } läuft in der aktuellen Shell. Eine Gruppe mit runden Klammern ( ... ) läuft in einer Subshell. Änderungen an Verzeichnis oder Variablen wirken sich entsprechend unterschiedlich auf die aufrufende Shell aus.

Portables Ausgabeformat -p

time -p sleep 1

-p verwendet POSIX-Stil real, user, sys Ausgabe. Dies ist nützlich, wenn Sie die Ergebnisse einfach auf mehreren Systemen parsen müssen, aber automatisierte Anforderungen einschließlich Gebietsschema und Genauigkeit müssen separat berücksichtigt werden.

Ausgabe in Bash mit TIMEFORMAT ändern

Die Ausgabe des Bash-Schlüsselworts kann mit der TIMEFORMAT-Variablen angepasst werden.

TIMEFORMAT='elapsed=%3R s user=%3U s sys=%3S s'
time sleep 1
Format Bedeutung
%R Verstrichene Zeit
%U CPU-Zeit im Benutzermodus
%S CPU-Zeit im Systemmodus
%P CPU-Auslastung als Prozentsatz anzeigen
%% Wörtliches Prozentzeichen

TIMEFORMAT wirkt sich auf die aktuelle Shell aus. Um es vorübergehend anzuwenden, bewahren Sie den vorhandenen Wert auf oder setzen Sie ihn innerhalb einer Subshell.

(
  TIMEFORMAT='elapsed=%R s'
  time ./job.sh
)

Externe GNU-Zeit verwenden

Geben Sie den vollständigen Pfad an, um die Optionen externer Befehle zuverlässig zu verwenden.

/usr/bin/time ./job.sh
/usr/bin/time -v ./job.sh

-v gibt detaillierte Informationen aus, die vom System bereitgestellt werden, wie maximaler Resident-Speicher, Seitenfehler, Dateisystem-I/O und Kontextwechsel. Die tatsächlichen Elemente und Werte können je nach Betriebssystem variieren.

Häufig verwendete Optionen von GNU time

Option Beschreibung
-p Gibt die Zeit im POSIX-Format aus.
-v Gibt detaillierte Statistiken zur Ressourcennutzung aus.
-f FORMAT Formatiert die Ausgabe mit Formatbezeichnern.
-o FILE Schreibt die Messergebnisse in die angegebene Datei.
-a -a Hängt an die Datei an, ohne sie zu überschreiben.

Gibt nur die Zeit und den Speicher im gewünschten Format aus

/usr/bin/time -f 'elapsed=%e max_rss=%MKB' ./job.sh

%e stellt die verstrichene Zeit dar, und %M stellt die maximale resident set size dar. Überprüfen Sie die Einheiten und Verfügbarkeit anhand des GNU Time-Handbuchs und Ihres aktuellen Systems.

Speichern Sie Messergebnisse in einer Datei

/usr/bin/time -v -o time-report.txt ./job.sh
/usr/bin/time -v -a -o time-report.txt ./job.sh

Die Verwendung von -o ermöglicht es Ihnen, den Standardfehler des gemessenen Befehls vom Zeitbericht zu trennen, was für die Automatisierung praktisch ist.

Warum die Zeit-Ausgabe an den Standardfehler geht

Zeitinformationen werden standardmäßig an den Standardfehler ausgegeben. Dies soll verhindern, dass die Zeitresultate mit der Standardausgabe des Befehls vermischt werden, wenn diese weitergeleitet oder in eine Datei umgeleitet wird.

time ./job.sh >job-output.txt

Dieser Befehl speichert nur die Standardausgabe des Jobs in einer Datei und zeigt die Zeitinformationen im Terminal an. Um nur die Zeitinformationen eines Bash-Builtins separat umzuleiten, müssen Sie die Standardfehlerausgabe der gesamten Gruppe behandeln, aber dies kann auch den eigenen Standardfehler des Jobs einschließen.

{ time ./job.sh >job-output.txt; } 2>time-and-errors.txt

Um nur den Zeitbericht zu trennen, ist die Verwendung des externen GNU Time -o klarer.

Punkte, auf die für einen genauen Vergleich zu achten ist

  • Die erste Ausführung und nachfolgende Ausführungen können sich aufgrund von Dateisystem-Caching, JIT-Kompilierung und Wiederverwendung von Verbindungen unterscheiden.
  • Kontrollieren Sie die Hintergrundlast, die CPU-Frequenzskalierung und Ressourcenkonflikte in virtuellen Maschinen.
  • Sehr kurze Befehle können Ergebnisse haben, die wesentlich durch den Messaufwand selbst beeinflusst werden.
  • Mehrfach wiederholen und den Median oder die Verteilung vergleichen.
  • Die Ausführungszeit kann variieren, je nachdem, ob das Ausgabegerät ein Terminal oder eine Datei ist.
  • Überprüfen Sie auch, ob der Geschwindigkeitsunterschied tatsächlich das Ergebnis der Aufgabe oder die Fehlerquote ändert.

Vergleich von Bash time und /usr/bin/time

Kategorie Bash time GNU /usr/bin/time
Typ Bash Schlüsselwörter Externe ausführbare Dateien
Pipeline Es ist einfach, die gesamte Pipeline direkt zu messen. Standardmäßig wird das angegebene Programm ausgeführt.
Shell-Funktionen und eingebaute Befehle Kann direkt gemessen werden. Es ist schwierig, direkt auszuführen, ohne eine separate Shell zu durchlaufen.
Detaillierte Ressourceninformationen Es konzentriert sich auf grundlegende Zeitstatistiken. Die Verwendung von -v liefert Statistiken wie Speicher und I/O.
Ausgabeanpassung TIMEFORMAT -f, -o, -a

Häufig gestellte Fragen

Kann die user-Zeit größer als die real-Zeit sein?

Ja. Wenn CPU-Zeiten mehrerer Prozesse oder Kerne kumuliert werden, kann die user-Zeit größer als die tatsächlich verstrichene real-Zeit sein.

time -v funktioniert nicht.

Dies könnte daran liegen, dass das reservierte Bash-Wort zuerst interpretiert wird. Wenn GNU Time installiert ist, verwenden Sie den vollständigen Pfad wie /usr/bin/time -v command.

Ändert time den Exit-Status eines Befehls?

Es gibt im Allgemeinen den Exit-Status des ausgeführten Befehls oder der gemessenen Pipeline zurück. In einer Pipeline kann das Ergebnis je nach der pipefail-Einstellung von Bash variieren.

Weitere Angaben zu Syntax, Implementierung und Verfügbarkeit finden Sie unter GNU Bash Handbuch: Pipelines und das reservierte Wort time und GNU Time Handbuch: Aufruf von time.