帶有時區的程序開始時間
我正在嘗試確定是否在啟動該過程後創建了文件。我正在使用 command 獲取程序開始時間
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 紀元時間是自歷史上的精確事件 (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 紀元時間:(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 和新創建的子 shell 的開始時間(這是在現代版本的 Linux 中以 CLK_TCK 表示的
)
字元最後一次出現後的第 20 個欄位/proc/pid/stat
),將差除以CLK_TCK
並添加到目前時間.