시간대가 포함된 프로세스 시작 시간

시간대가 포함된 프로세스 시작 시간

프로세스를 시작한 후 파일이 생성되었는지 확인하려고 합니다. 프로세스 시작 시간을 얻기 위해 명령을 사용하고 있습니다 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 날짜와 같은 다른 형식을 사용하여 프로세스 시작 시간을 얻을 수 있습니까? (밀리초를 갖는 것도 도움이 될 것입니다)

컨텍스트: psGo 애플리케이션에서 명령을 실행하고 결과를 구문 분석하고 있습니다.

답변1

파일 시스템은 시간대가 포함된 시간을 제공하지 않습니다. 시간을 현지 시간( /etc/localtime또는 $TZ시간대 제공 기타).

일반적으로 Unix의 타임스탬프는 시간대 독립적인 방식으로 표시됩니다. 유닉스 에포크 시간은 역사상 정확한 사건입니다(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

GNU는 date보고된 날짜를 구문 분석할 수 있으므로 ps이를 unix epoch 시간과 같은 모든 형식으로 변환할 수 있습니다.

(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분기된 시간에 해당합니다 .straceps

1/$(getconf CLK_TCK)1초 미만의 정확도(최대 ) 를 얻으려면 를 사용하고 zsh다음을 수행할 수 있습니다.

zmodload zsh/datetime
tick=$(getconf CLK_TCK)
(echo $((EPOCHREALTIME + (${${=$(</proc/self/stat)##*)}[20]}. -
          ${${=$(</proc/$pid/stat)##*)}[20]})/tick)))

즉, $pid와 새로 생성된 서브쉘의 시작 시간(최신 버전의 Linux에서 CLK_TCK로 표시되는 문자가 마지막으로 나타난 후 20번째 필드 )) 을 가져와서 /proc/pid/stat그 차이를 나누어 CLK_TCK현재 시간에 추가합니다.

관련 정보