Я пытаюсь определить, создается ли файл после запуска процесса или нет. Я получаю время начала процесса, используя команду ps -f -p PID -o lstart=
. Это дает мне результат, например, Fri May 5 09:15:35 2017
, который не имеет информации о часовом поясе.
С другой стороны, файловая система дает мне даты с часовым поясом. Когда я сравниваю даты, я получаю неправильный результат. Пример:
2017-05-05 10:26:57 +0000 UTC
2017-05-05 10:26:57.679508679 +0200 CEST
Возможно ли получить время начала процесса в другом формате, например, в качестве даты unix? (Иметь миллисекунды тоже помогут)
Контекст: я запускаю команду ps
из приложения go и анализирую результат.
Файловая система не дает вам времени с часовым поясом, это какая-то команда, которую вы используете для отображения этого времени в дружественном для человека формате, который может дать вам часовой пояс, если он хочет отображать время в локальное время (как указано в /etc/localtime
, $TZ
или другое).
Как правило, временные метки в Unix выражаются способом, который не имеет отношения к часовым поясам. Время эпохи unix – это количество секунд (секунд, выраженное как 86400-я часть дня, так варьирующееся по длине, но более полезное для календарного расчета), поскольку точное событие в истории (1970-01-01 00:00:00 UTC, недвусмысленное время). Часовые пояса появляются только при отображении даты в календарном формате для человека.
ps -o lstart= -p "$pid" date -r /some/file
оба дают вам местное время. date
может выводить смещение часового пояса или не зависящее от языкового стандарта. Если вы хотите время UTC, запустите их в TZ=UTC0
:
TZ=UTC0 ps -o lstart= -p "$pid" TZ-UTC0 date -r /some/file # or use date -u
date
GNU может анализировать дату, ps
, поэтому вы можете преобразовать ее в любой формат, например, в эпоху unix:
(export TZ=UTC0 date -d "$(ps -o lstart -p "$pid") +%s date -r /some/file +%s)
(выше, используя время UTC, оно также будет работать с любым местным временем в вашей среде, за исключением одного часа в году, когда вывод времени без индикации TZ неоднозначен (в зонах, которые реализуют DST)).
В любом случае, время начала процесса не обязательно должно быть (и никогда точно) – время, в течение которого выполнялась команда, выполняемая в данный момент. Например:
$ 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
Этот процесс 9397 запускает 4 команды за время своей жизни: strace
(раздвоенный там), sh
, env
, ps
. Время, сообщаемое ps
соответствует времени, когда оно было раздвоено strace
, а не когда оно выполнялось ps
.
Если вы хотите получить субсекундную точность (до 1/$(getconf CLK_TCK)
), с zsh
, вы можете сделать:
zmodload zsh/datetime tick=$(getconf CLK_TCK) (echo $((EPOCHREALTIME + (${${=$(</proc/self/stat)##*)}[20]}. - ${${=$(</proc/$pid/stat)##*)}[20]})/tick)))
То есть мы получаем начальное время $ pid и вновь созданного подоболочка (это 20 полей после последнего появления символа a )
в /proc/pid/stat
выраженное в CLK_TCK в современных версиях Linux), разделите разницу CLK_TCK
и добавить к текущему времени.