公众号旧文
真正精确的运行时间看 ps 的 etime 最方便
#Linux
在 Linux 服务器运维中,我们经常需要判断一个进程到底运行了多久。
很多人第一反应会使用:
systemctl status 服务名
例如:
systemctl status china-exit-ip-scan.service
输出可能类似:
Active: activating (start) since Fri 2026-08-14 14:07:28 CST; 2 days ago
乍一看,我们很容易理解成:
这个服务运行了大约两天。
但这里有一个细节:systemctl status 后面的 2 days ago 是为了方便人阅读而显示的相对时间,它并不是一个适合精确计算运行时长的字段。
如果我们真正想知道:
这个进程到底已经连续运行了几天、几小时、几分钟?
那么更方便的方法,是直接查看 ps 的 etime。
一、systemctl status 的时间并不够精确
例如一个任务显示:
Active: activating (start) since Fri 2026-08-14 14:07:28 CST; 2 days ago
这里实际上同时包含了两种时间信息。
第一种是精确启动时间:
Fri 2026-08-14 14:07:28 CST
第二种是人类可读的相对时间:
2 days ago
问题就在第二部分。
2 days ago 只是一个粗粒度的描述。
例如一个任务已经运行:
48 小时
51 小时
60 小时
70 小时
都有可能在一段时间内显示成:
2 days ago
它不会告诉你:
2 天 3 小时 36 分
还是:
2 天 20 小时
所以如果只是快速判断服务是不是几天前启动的,systemctl status 很方便。
但如果需要精确判断运行时间,它就不够直观了。
二、直接使用 ps 查看 etime
Linux 的 ps 命令提供了一个非常实用的字段:
etime
它表示:
Elapsed Time,即进程从启动到现在经过的真实墙钟时间。
例如:
ps -p 1653274 -o pid,lstart,etime,time,cmd
输出:
PID STARTED ELAPSED TIME CMD
1653274 Fri Aug 14 14:07:27 2026 2-03:36:03 10:49:31 python3 -u scanner-v6.py
这里最值得关注的是:
ELAPSED
2-03:36:03
它的格式是:
天-小时:分钟:秒
所以:
2-03:36:03
表示:
2 天
3 小时
36 分钟
3 秒
也就是:
这个 Python 进程已经连续运行了 51 小时 36 分 3 秒。
相比 systemctl status 的:
2 days ago
显然精确得多。
三、不要把 etime 和 time 搞混
ps 里还有另一个很容易混淆的字段:
time
例如:
ELAPSED TIME
2-03:36:03 10:49:31
这两个数字含义完全不同。
etime
表示:
从进程启动到现在经过了多久
也就是实际现实世界中的时间。
例如:
2-03:36:03
表示程序启动已经超过两天。
time
表示:
进程累计实际使用了多少 CPU 时间
例如:
10:49:31
表示这个进程累计消耗了:
10 小时 49 分 31 秒 CPU 时间
所以一个程序完全可能出现:
ELAPSED = 51 小时
TIME = 10 小时
这并不矛盾。
它说明剩余的大量时间可能花在:
- 等待网络响应
- 等待磁盘 I/O
- 等待其他子进程
- socket timeout
- HTTP 请求
- nmap 扫描
- sleep
- 系统调度
对于网络扫描程序来说,这种情况尤其常见。
四、lstart 可以直接看到准确启动时间
除了 etime,另一个非常实用的字段是:
lstart
例如:
ps -p 1653274 -o lstart
输出:
Fri Aug 14 14:07:27 2026
lstart 的意思是:
Long Start Time
也就是进程完整的启动日期和时间。
因此在排查长期运行任务时,可以把:
lstart
etime
time
三个字段一起看。
例如:
ps -p 1653274 -o pid,lstart,etime,time,cmd
一次就能知道:
什么时候启动
已经运行多久
用了多少 CPU
运行的是什么程序
五、为什么 systemctl show ActiveEnterTimestamp 有时是空的
有时候我们还会尝试:
systemctl show china-exit-ip-scan.service \
-p ActiveEnterTimestamp \
-p ActiveEnterTimestampMonotonic
结果却是:
ActiveEnterTimestamp=
ActiveEnterTimestampMonotonic=0
这并不一定代表 systemd 出问题了。
例如服务当前状态是:
Active: activating (start)
意味着这个 service 还处于启动过程中。
如果它对应的是一个长时间运行、执行完才退出的脚本,那么 systemd 可能一直认为:
activating
而还没有真正进入:
active
状态。
既然没有进入 active,自然也就不存在:
ActiveEnterTimestamp
这种情况下,直接查看真正执行任务的进程:
ps
反而更加直接。
六、长期任务最推荐的查看方式
对于扫描器、备份任务、同步任务、爬虫、大数据处理脚本这类可能运行数小时甚至数天的进程,我通常建议直接使用:
ps -p PID -o pid,lstart,etime,time,%cpu,%mem,cmd
例如:
ps -p 1653274 \
-o pid,lstart,etime,time,%cpu,%mem,cmd
这样可以同时得到:
PID
启动时间
已经运行时间
累计 CPU 时间
CPU 占用
内存占用
完整命令
比单纯查看:
systemctl status
更适合分析一个长期任务到底发生了什么。
七、不知道 PID 时,可以自动查找
如果 PID 每次都会变化,也没必要手动先查 PID。
例如一个 Python 程序:
scanner-v6.py
可以直接:
pgrep -af scanner-v6.py
找到进程。
也可以组合成:
ps -p $(pgrep -f 'python3 -u scanner-v6.py' | head -1) \
-o pid,lstart,etime,time,%cpu,%mem,cmd
以后只要执行这一条,就能快速看到当前扫描器的运行状态。
八、如何判断一个任务是不是“卡死”
etime 还有一个很实用的用途,就是帮助判断长期任务是否真的卡住。
假设:
ELAPSED
2-03:36:03
只能说明任务已经运行两天多。
它本身不能证明任务卡死。
还需要结合:
TIME
以及日志、子进程状态一起判断。
例如隔半小时查看两次:
第一次:
ELAPSED: 2-03:36:03
TIME: 10:49:31
第二次:
ELAPSED: 2-04:06:03
TIME: 11:03:42
说明:
墙钟时间增加 30 分钟
CPU 时间也增加了 14 分钟
这通常说明程序仍然在持续执行。
如果同时还能看到:
nmap ...
或者日志持续出现:
[SCAN]
[CHECK]
[FOUND]
[SKIP]
那么基本可以确认:
程序只是运行时间很长,并没有真正卡死。
反过来,如果连续几个小时:
etime 不断增加
CPU time 几乎不增加
日志完全没有新内容
没有任何子进程变化
这时候才值得进一步检查:
- 网络请求是否无限等待
- timeout 是否失效
- subprocess 是否挂起
- 文件锁
- socket 阻塞
- 死循环或死锁
九、运维中应该怎么选
简单来说,可以这样记:
想看服务整体状态
→ systemctl status
想看进程什么时候启动
→ ps 的 lstart
想看真正运行了多久
→ ps 的 etime
想看累计用了多少 CPU
→ ps 的 time
想看当前资源占用
→ %cpu / %mem
其中对于长期运行任务:
真正精确的运行时间,看
ps的etime最方便。
例如:
ps -p PID -o pid,lstart,etime,time,cmd
这是一个非常简单,却非常实用的 Linux 运维习惯。
当一个任务已经运行几十个小时以后,与其盯着:
2 days ago
猜它究竟运行了多久,不如直接看:
2-03:36:03
数字会告诉你准确答案。