我有一个文件,其内容是
PID
Tab STARTTIME
我想知道这个过程是否还存在。
我可以检查给定的 PID 是否正在运行:
kill -0 "$pid" && echo alive
但是它缺乏区分真实进程和另一个具有相同 PID 的进程的能力。
所以我虽然使用
ps
:
ps -o lstart= "$pid"
但是它出错了:
ps: unknown output format: -o lstart
是否有 POSIX 方法从 shell 中获取给定 PID 的开始时间(自 EPOCH 以来的秒数)?
正如@Cyrus 指出的那样,我们可以处理
ps -o etime=
的输出以获得给定 PID 的开始时间:
get_starttime() {
awk -v pid="$1" '
BEGIN {
cmd = "ps -o etime= " pid
if ( (cmd | getline) > 0 )
now = (srand() ? srand() : srand())
else
exit 1
n = split($NF, a, "[:-]")
print now - a[n-3]*86400 - a[n-2]*3600 - a[n-1]*60 - a[n]
}
'
}
好吧,它更像是一个“近似值”,因为当我将它与 Linux 中
ps -o lstart=
提供的开始“日期”进行比较时,我没有得到相同的结果:
#!/bin/bash
get_starttime() { ... }
while read pid lstart
do
starttime=$(get_starttime "$pid") &&
printf '%s\t%s\n' "$starttime" "$(date -d "$lstart" +%s)"
done < <(
ps -e -o pid= -o lstart=
)
虽然有些出入,但相差似乎不会超过1秒;因此,我认为我们仍然可以使用它来检测一个进程在不需要太多精度的环境中是否存活(例如在 crontab 中):
is_alive() {
awk -v pid="$1" -v starttime="$2" '
BEGIN {
cmd = "ps -o etime= " pid
cmd | getline
now = (srand() ? srand() : srand())
n = split($NF, a, "[:-]")
d = starttime - now + a[n-3]*86400 + a[n-2]*3600 + a[n-1]*60 + a[n]
exit (d < -1 || 1 < d)
}
'
}
pid=...
starttime=...
if is_alive "$pid" "$starttime"
then
echo "$pid is alive"
else
echo "$pid is dead"
fi