タイムゾーンを含むプロセス開始時間

タイムゾーンを含むプロセス開始時間

プロセスを開始した後、ファイルが作成されたことを確認しようとしています。プロセスの開始時間を取得するためにコマンドを使用しています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のタイムスタンプはタイムゾーンに依存しない方法で表示されます。 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、、、、envps報告された時間は、実行された時間ではなく、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現在時刻に追加します。

おすすめ記事