Ich versuche festzustellen, ob eine Datei nach dem Start des Prozesses erstellt wird oder nicht. Ich erhalte die Startzeit des Prozesses mit dem Befehl ps -f -p PID -o lstart=
. Dies gibt mir ein Ergebnis wie Fri May 5 09:15:35 2017
die keine Zeitzoneninformationen enthält.
Auf der anderen Seite gibt mir das Dateisystem Daten mit Zeitzone. Wenn ich Daten vergleiche, erhalte ich ein falsches Ergebnis. Beispiel:
- Prozessstart:
2017-05-05 10:26:57 +0000 UTC
- Datei geändert:
2017-05-05 10:26:57.679508679 +0200 CEST
Ist es möglich, die Startzeit des Prozesses in einem anderen Format zu erhalten, beispielsweise als Unix-Datum? (Millisekunden zu haben würde auch helfen)
Kontext:Ich führe ps
aus Befehl aus einer Go-Anwendung und Parsing des Ergebnisses.
Akzeptierte Antwort:
Das Dateisystem gibt Ihnen keine Zeit mit Zeitzone, es ist der Befehl, den Sie verwenden, um diese Zeit in einem benutzerfreundlichen Format anzuzeigen, der Ihnen möglicherweise eine Zeitzone gibt, wenn es sich dafür entscheidet, die Zeit in Ortszeit anzuzeigen (wie durch /etc/localtime
, $TZ
oder andere).
Im Allgemeinen werden Zeitstempel auf Unix auf eine Weise ausgedrückt, die für Zeitzonen irrelevant ist. Die Unix-Epochenzeit ist die Anzahl der Sekunden (Sekunden ausgedrückt als 86400. Teil eines Tages, daher unterschiedlich lang, aber nützlicher für die Kalenderberechnung) seit einem präzisen Ereignis in der Geschichte (1970-01-01 00:00:00 UTC, eine eindeutige Zeit). Zeitzonen kommen nur ins Spiel, wenn einem Menschen ein Datum in einem Kalenderformat angezeigt wird.
ps -o lstart= -p "$pid"
date -r /some/file
beide geben Ihnen die Ortszeit. date
kann je nach Gebietsschema den Zeitzonenoffset ausgeben oder nicht. Wenn Sie die UTC-Zeit möchten, führen Sie sie unter TZ=UTC0
aus :
TZ=UTC0 ps -o lstart= -p "$pid"
TZ-UTC0 date -r /some/file # or use date -u
GNU date
kann das von ps
gemeldete Datum analysieren , sodass Sie es in ein beliebiges Format konvertieren können, z. B. die Unix-Epochenzeit:
(export TZ=UTC0
date -d "$(ps -o lstart -p "$pid") +%s
date -r /some/file +%s)
(oben mit UTC-Zeit. Es würde auch mit der Ortszeit in Ihrer Umgebung funktionieren, mit Ausnahme einer Stunde im Jahr, in der eine Zeitausgabe ohne TZ-Angabe mehrdeutig ist (in Zonen, die DST implementieren)).
In jedem Fall muss die Startzeit eines Prozesses nicht (und ist niemals genau) die Zeit sein, zu der der Prozess den Befehl ausgeführt hat, den er gerade ausführt. Zum Beispiel:
$ TZ=UTC0 strace -qtt -e execve sh -c 'sleep 3; exec env ps -o lstart= -p "$$"'
10:27:24.877397 execve("/bin/sh", ["sh", "-c", "sleep 3; exec env ps -o lstart= "...], [/* 28 vars */]) = 0
10:27:27.882553 execve("/usr/bin/env", ["env", "ps", "-o", "lstart=", "-p", "9397"], [/* 28 vars */]) = 0
10:27:27.885272 execve("/bin/ps", ["ps", "-o", "lstart=", "-p", "9397"], [/* 28 vars */]) = 0
Fri May 5 10:27:24 2017
Dieser 9397-Prozess führt in seiner Lebenszeit 4 Befehle aus:strace
(dort gegabelt), sh
, env
, ps
. Die von ps
gemeldete Zeit entspricht dem Zeitpunkt, an dem es von strace
gegabelt wurde , nicht wenn ps
ausgeführt wurde .
Wenn Sie eine Genauigkeit von weniger als einer Sekunde erhalten möchten (bis zu 1/$(getconf CLK_TCK)
), mit zsh
, könnten Sie Folgendes tun:
zmodload zsh/datetime
tick=$(getconf CLK_TCK)
(echo $((EPOCHREALTIME + (${${=$(</proc/self/stat)##*)}[20]}. -
${${=$(</proc/$pid/stat)##*)}[20]})/tick)))
Das heißt, wir erhalten die Startzeit der $pid und einer neu erstellten Subshell (das ist das 20. Feld nach dem letzten Auftreten eines )
Zeichen in /proc/pid/stat
in modernen Versionen von Linux in CLK_TCK ausgedrückt), teilen Sie die Differenz durch CLK_TCK
und zur aktuellen Zeit hinzufügen.