如何检查进程运行了多长时间?


242

我想通过从监视应用程序启动该过程来避免这样做。

Answers:


311

在具有psfrom的Linux上procps(-ng)(以及大多数其他系统,因为这是POSIX指定的):

ps -o etime= -p "$$" 

$$您要检查的流程的PID 在哪里。这将以格式返回经过的时间[[dd-]hh:]mm:ss

利用-o etime告诉ps你只是想用时间字段,并=在该月底抑制头(没有,你会得到一个线,说ELAPSED再下一行时间;用,你用的时间只有一行) 。

或者,在Linux或FreeBSD 9.0或更高版本(可能还有其他)上,使用较新版本的procps-ng工具套件(3.3.0或更高版本),请使用:

ps -o etimes= -p "$$"

(添加了s)以将时间格式化为秒,这在脚本中更为有用。

在Linux上,ps程序从中获取此信息/proc/$$/stat,其中一个字段(请参阅参考资料man proc)是进程开始时间。不幸的是,这被指定为自系统启动以来的时间(以jiffies为单位)(Linux内核中使用的任意时间计数器)。因此,您必须确定系统的启动时间(从开始/proc/stat),该系统上每秒的跳动次数,然后进行数学计算以获得有用的格式。

找出HZ的值(即每秒jiffies)变得非常复杂。从sysinfo.cprocps软件包中的注释中,可以A)包含内核头文件并在使用其他内核的情况下重新编译; B)使用posix sysconf()函数,可悲的是,该函数使用编译到C库中的硬编码值;或者C)询问内核,但是没有正式的接口可以这样做。因此,该ps代码包括一系列错误,由此可以确定正确的值。哇。

因此ps,为您完成所有操作很方便。:)

正如用户@ 336_所指出的那样,在Linux(这是不可移植的)上,您可以使用stat命令查看目录的访问,修改或状态更改日期/proc/$$(这里$$是您感兴趣的过程)。三个数字都应该相同,所以

stat -c%X /proc/$$

$$自开始起以秒为单位,将为您提供该过程开始的时间。那仍然不是您想要的,因为您仍然需要进行数学运算以从当前时间中减去该时间以获得经过的时间-我想类似的方法date +%s --date="now - $( stat -c%X /proc/$$ ) seconds"会起作用,但这有点笨拙。一种可能的优势是,如果您使用长格式输出(例如-c%x而不是)-c%X,则可获得比整数秒更大的分辨率。但是,如果需要,则可能应该使用过程审核方法,因为运行stat命令的时间会影响准确性。


1
嗨!是etime=错字吗?我只能etime在手册页中找到。
肯特·帕瓦尔

16
@KentPawar不是错字。空=抑制标题。不尝试也可以尝试ps -p $$ -o etime="Silly Header Here"
mattdm 2013年

4
ps -p $(pgrep find)-o etime =
mafrosis

1
真好 我更喜欢etimes自己,因为它可以机读
Asfand Qazi

1
@alexmurray如前所述,它只是调用sysconf()并因此为您提供了C库中的硬编码值,不是吗?
mattdm '16

36

便携式:

% ps -o stime,time $$
STIME     TIME
Jan30 00:00:06

也就是说,该外壳程序于1月30日启动,总共耗时约6秒。

可能会有更精确或更可解析但可移植性较低的方式来获取此信息。检查ps命令或proc文件系统的文档。

在Linux下,此信息位于中/proc/$pid/stat

awk '{print "CPU time: " $14+$15; print "start time: " $22}' /proc/$$/stat

CPU时间紧张。我不知道如何从shell中找到jiffy值。开始时间与引导时间有关(位于中/proc/uptime)。


3
找出HZ的值(即每秒抖动),结果非常复杂!从sysinfo.cprocps软件包中的注释中,可以a)包含内核头文件(如果使用其他内核,则重新编译,b)使用posix sysconf()函数,可悲的是,该函数使用硬编码值编译为c库,或c)询问内核,并且没有官方接口可以执行此操作。因此,该代码包括一系列错误,由此可以确定正确的值。哇。
mattdm 2011年

1
该手册ps页指出time“ CPU时间累计”。我认为OP一直在寻找什么etime,或者是“自流程启动以来经过的时间”。pubs.opengroup.org/onlinepubs/000095399/utilities/ps.html
rinogo 2014年

1
毕竟不是那么“便携”:在FreeBSD上是“ ps:stime:找不到关键字”。不过,它至少支持etime
n.st


13

ps使用一个-o选项来指定输出格式,并且可用列之一是etime。根据手册页:

etime-自进程开始以来经过的时间,格式为[[dd-] hh:] mm:ss。

因此,您可以运行此命令以获取每个进程的PID和已用时间:

$ ps -eo pid,etime

如果要使用特定PID的经过时间(例如12345),则可以执行以下操作:

$ ps -eo pid,etime | awk '/^12345/ {print $2}'

编辑:原来上述命令的语法较短;请参见mattdm的答案


5

不确定为什么尚未建议这样做:在Linux上,您可以stat()将/ proc / [nnn]目录用作PID。

明确设计此行为是为了返回进程的开始时间,它可以在高分辨率下执行,并且内核可以(显然)可以简单地检查相关信息,因此可以在没有麻烦的情况下准确地执行操作。访问,数据修改和状态更改字段均返回过程开始时间。

最重要的是,您可以stat(1)在shell上使用它,也可以在stat(2)$ favorite_programming_language上进行适当的绑定,因此甚至不需要启动外部进程。

注意,这并不会与工作/usr/compat/linux/proc在FreeBSD; 返回的访问/修改/状态更改时间是当前时间,而出生时间是UNIX纪元。如果您问我,那是很愚蠢的支持不存在的地方。


在stat的输出中哪里可以看到该信息?我只看到访问,修改和更改。
tshepang

@Tshepang请注意,这些值都相同,它们进程的开始时间。您仍然必须进行数学运算,但这绝对比我在答案中指出的尝试变硬更好。
mattdm

您这样称呼它:stat /proc/4480这将为您提供该过程的出生,更改,修改和访问日期。如果您需要进程ID,只需使用“顶部”
user890332,

2

如果您可以运行时间然后执行命令,则将完全获得所需的内容。您不能对已经运行的命令执行此操作。

[0]睡眠时间百分比20

睡眠20 0.00s用户0.00s系统0%cpu 20.014总计


您知道如何在运行中的过程监控中执行该操作直到结束?
lrkwz 2012年

1

您可以通过查看由stat产生的stat文件的来获得该过程的开始时间,proc使用对其进行格式化date并从当前时间中减去它:

echo $(( $(date +%s) - $(date -d "$(stat /proc/13494/stat | grep Modify | sed 's/Modify: //')" +%s) ))

13494您的进程的pid 在哪里


1

$ ps -eo lstart 开始时间

$ ps -eo etime 获取持续时间/经过时间

$ ps -eo pid,lstart,etime | grep 61819
  PID                   STARTED     ELAPSED
  61819 Mon Sep 17 03:01:35 2018    07:52:15

61819是进程ID。


lstart的使用可能是有问题的,它会歪斜- unix.stackexchange.com/questions/274610/...
SLM

1

经过的时间(以秒为单位): expr $(date +"%s") - $(stat -c%X /proc/<PID HERE>)


在我看来,这是mattdm已经提到的内容的非常细微的变化: date +%s --date="now - $( stat -c%X /proc/$$
杰夫·

那个在我最小的Alpine
docker
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.