J'essaie d'identifier si un fichier est créé après le démarrage du processus ou non. J'obtiens l'heure de début du processus à l'aide de la commande ps -f -p PID -o lstart=
. Cela me donne un résultat tel que Fri May 5 09:15:35 2017
qui n'a aucune information de fuseau horaire.
D'autre part, le système de fichiers me donne des dates avec le fuseau horaire. Lorsque je compare des dates, j'obtiens le mauvais résultat. Exemple :
- début du processus :
2017-05-05 10:26:57 +0000 UTC
- fichier modifié :
2017-05-05 10:26:57.679508679 +0200 CEST
Est-il possible d'obtenir l'heure de début du processus avec un format différent, par exemple en tant que date unix ? (Avoir des millisecondes aiderait aussi)
Contexte :j'exécute le ps
commande à partir d'une application go et analyse du résultat.
Réponse acceptée :
Le système de fichiers ne vous donne pas d'heure avec le fuseau horaire, c'est la commande que vous utilisez pour afficher cette heure dans un format convivial qui peut vous donner un fuseau horaire s'il choisit d'afficher l'heure en heure locale (comme spécifié par /etc/localtime
, $TZ
ou autre).
Généralement, les horodatages sur Unix sont exprimés d'une manière qui n'est pas pertinente pour les fuseaux horaires. L'heure d'époque unix est le nombre de secondes (secondes exprimées comme la 86400e partie d'un jour, donc de longueur variable mais plus utile pour le calcul du calendrier) depuis un événement précis dans l'histoire (1970-01-01 00:00:00 UTC, un temps sans ambiguïté). Les fuseaux horaires n'entrent en ligne de compte que lors de l'affichage d'une date au format calendrier à un humain.
ps -o lstart= -p "$pid"
date -r /some/file
les deux vous donnent l'heure locale. date
peut afficher ou non le décalage du fuseau horaire en fonction des paramètres régionaux. Si vous voulez l'heure UTC, exécutez-les sous TZ=UTC0
:
TZ=UTC0 ps -o lstart= -p "$pid"
TZ-UTC0 date -r /some/file # or use date -u
GNU date
est capable d'analyser la date rapportée par ps
, afin que vous puissiez le convertir dans n'importe quel format, comme l'heure d'époque unix :
(export TZ=UTC0
date -d "$(ps -o lstart -p "$pid") +%s
date -r /some/file +%s)
(au-dessus de l'utilisation de l'heure UTC. Cela fonctionnerait également quelle que soit l'heure locale de votre environnement, sauf pour une heure de l'année où une sortie d'heure sans indication TZ est ambiguë (dans les zones qui implémentent l'heure d'été)).
Dans tous les cas, l'heure de début d'un processus ne doit pas nécessairement être (et n'est jamais exactement) l'heure à laquelle le processus a exécuté la commande qu'il est en train d'exécuter. Par exemple :
$ 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
Ce processus 9397 exécute 4 commandes dans sa durée de vie :strace
(fourchu là), sh
, env
, ps
. Le temps rapporté par ps
correspond au moment où il a été forké par strace
, pas quand il a exécuté ps
.
Si vous souhaitez obtenir une précision inférieure à la seconde (jusqu'à 1/$(getconf CLK_TCK)
), avec zsh
, vous pourriez faire :
zmodload zsh/datetime
tick=$(getconf CLK_TCK)
(echo $((EPOCHREALTIME + (${${=$(</proc/self/stat)##*)}[20]}. -
${${=$(</proc/$pid/stat)##*)}[20]})/tick)))
C'est-à-dire que nous obtenons l'heure de début du $pid et d'un sous-shell nouvellement créé (c'est-à-dire le 20e champ après la dernière occurrence d'un )
caractère dans /proc/pid/stat
exprimé en CLK_TCK dans les versions modernes de Linux), divisez la différence par CLK_TCK
et ajouter à l'heure actuelle.