Process

帶有時區的程序開始時間

  • May 5, 2017

我正在嘗試確定是否在啟動該過程後創建了文件。我正在使用 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

GNUdate能夠解析 報告的日期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、、、、envps報告的時間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並添加到目前時間.

引用自:https://unix.stackexchange.com/questions/363193