プロセスを開始した後、ファイルが作成されたことを確認しようとしています。プロセスの開始時間を取得するためにコマンドを使用しています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アプリケーションでコマンドを実行し、結果を解析しています。
答え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
、、、、env
。ps
報告された時間は、実行された時間ではなく、ps
分岐された時間に対応します。strace
ps
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
現在時刻に追加します。