Sto cercando di identificare se un file viene creato dopo aver avviato il processo o meno. Ricevo l'ora di inizio del processo utilizzando il comando ps -f -p PID -o lstart=
. Questo mi dà un risultato come Fri May 5 09:15:35 2017
che non ha alcuna informazione sul fuso orario.
D'altra parte, il file system mi fornisce date con fuso orario. Quando confronto le date ottengo il risultato sbagliato. Esempio:
- inizio processo:
2017-05-05 10:26:57 +0000 UTC
- file modificato:
2017-05-05 10:26:57.679508679 +0200 CEST
È possibile ottenere l'ora di inizio del processo con un formato diverso, ad esempio come data unix? (Avere anche i millisecondi aiuterebbe)
Contesto:sto eseguendo ps
comando da un'applicazione go e analizzare il risultato.
Risposta accettata:
Il file system non ti dà un'ora con il fuso orario, è qualsiasi comando che usi per visualizzare quell'ora in un formato adatto all'uomo che potrebbe darti un fuso orario se sceglie di visualizzare l'ora nell'ora locale (come specificato da /etc/localtime
, $TZ
o altro).
In genere, i timestamp su Unix sono espressi in un modo irrilevante per i fusi orari. L'epoca unix è il numero di secondi (secondi espressi come 86400a parte di un giorno, quindi di lunghezza variabile ma più utile per il calcolo del calendario) da un preciso evento nella storia (1970-01-01 00:00:00 UTC, un tempo inequivocabile). I fusi orari vengono visualizzati solo quando si visualizza una data in formato calendario a un essere umano.
ps -o lstart= -p "$pid"
date -r /some/file
entrambi ti danno l'ora locale. date
potrebbe emettere l'offset del fuso orario o meno a seconda delle impostazioni locali. Se desideri l'ora UTC, eseguili in TZ=UTC0
:
TZ=UTC0 ps -o lstart= -p "$pid"
TZ-UTC0 date -r /some/file # or use date -u
GNU date
è in grado di analizzare la data riportata da ps
, quindi puoi convertirlo in qualsiasi formato, come unix epoch time:
(export TZ=UTC0
date -d "$(ps -o lstart -p "$pid") +%s
date -r /some/file +%s)
(sopra usando l'ora UTC. Funzionerebbe anche con qualunque sia l'ora locale nel tuo ambiente tranne un'ora nell'anno in cui un'uscita dell'ora senza indicazione TZ è ambigua (nelle zone che implementano l'ora legale)).
In ogni caso, l'ora di inizio di un processo non deve essere (e non è mai esattamente) l'ora in cui il processo ha eseguito il comando che è attualmente in esecuzione. Ad esempio:
$ 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
Quel processo 9397 esegue 4 comandi nella sua vita:strace
(biforcato lì), sh
, env
, ps
. Il tempo riportato da ps
corrisponde al momento in cui è stato biforcato da strace
, non quando ha eseguito ps
.
Se vuoi ottenere una precisione inferiore al secondo (fino a 1/$(getconf CLK_TCK)
), con zsh
, potresti fare:
zmodload zsh/datetime
tick=$(getconf CLK_TCK)
(echo $((EPOCHREALTIME + (${${=$(</proc/self/stat)##*)}[20]}. -
${${=$(</proc/$pid/stat)##*)}[20]})/tick)))
Otteniamo l'ora di inizio del $pid e di una sottoshell appena creata (sono i 20 campi dopo l'ultima occorrenza di un )
carattere in /proc/pid/stat
espresso in CLK_TCK nelle versioni moderne di Linux), dividere la differenza per CLK_TCK
e aggiungi all'ora corrente.