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

#1 楼

在具有ps中的procps(-ng)的Linux上(以及大多数其他系统,因为这是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)是进程开始时间。不幸的是,这被指定为自系统启动以来的时间(即Linux内核中使用的任意时间计数器)。因此,您必须确定系统启动时间(从/proc/stat),该系统上每秒的跳动次数,然后进行数学计算以获得有用的格式。

找出HZ的值(即每秒jiffies)变得非常复杂。根据procps软件包中sysinfo.c的注释,可以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命令的时间会影响准确性。

评论


嗨! etime =是错字吗?我只能在手册页中找到etime。

–肯特·帕瓦尔(Kent Pawar)
13年6月27日在13:01

@KentPawar这不是错字。 empty =禁止显示标题。尝试不使用它,或尝试ps -p $$ -o etime =“ Silly Header Here”

–mattdm
13年6月27日在13:28

ps -p $(pgrep找到)-o etime =

–乳房畸形
2013年9月11日23:07

真好我更喜欢etimes,因为它可以机读

–阿斯范·卡兹
15年7月15日在9:35

@alexmurray那只是调用sysconf(),因此如上所述,您从C库中获得了硬编码的值,不是吗?

–mattdm
16-4-1在1:55



#2 楼

便携式:

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


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

获取此信息的方法可能更精确或更可解析,但更不便于移植。请查看ps命令或proc文件系统的文档。

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

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


CPU时间为跳动我不知道如何从shell中找到jiffy值。开始时间与引导时间有关(请参见/proc/uptime)。

评论


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

–mattdm
2011-2-22在21:54

ps联机帮助页指出时间是“累计CPU时间”。我认为OP所需的时间是etime,即“自流程启动以来经过的时间”。 pubs.opengroup.org/onlinepubs/000095399/utilities/ps.html

– rinogo
2014年4月23日20:35



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

–n.st
16年5月23日在11:34

#3 楼

ps -eo pid,comm,cmd,start,etime | grep -i X


X是进程的名称

评论


应该添加一个grep -v grep。

–布赖恩
14年6月30日在20:07

ps -o pid,comm,cmd,start,etime -p X查看PIDX。

– codeforester
18年7月9日在17:06

#4 楼

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


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


因此,您可以运行它来获取每个进程的PID和经过时间:

12345),您可以执行以下操作:

$ ps -eo pid,etime


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

#5 楼

不确定为什么尚未建议这样做:在Linux上,您可以为PID的/ proc / [nnn]目录设置stat()。内核可以(很明显)简单地检查相关信息,因此内核可以准确地执行此操作而不会受到干扰。访问,数据修改和状态更改字段均返回进程的开始时间。

最好的是,您可以在外壳上使用stat(1),或从$ favorite_programming_language适当地绑定到stat(2),因此您可以

请注意,这不适用于FreeBSD上的/usr/compat/linux/proc;返回的访问/修改/状态更改时间是当前时间,而出生时间是UNIX纪元。如果您问我,支持服务就很愚蠢。

评论


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

– tshepang
17年1月8日在22:52

@Tshepang请注意,这些值都相同,并且它们是进程的开始时间。您仍然必须进行数学计算,但这绝对比尝试按照我的回答指出的那样更好。

–mattdm
17 Mar 2 '17 at 16:53

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

–user890332
19年8月21日在17:05



#6 楼

如果您可以运行时间然后执行命令,您将获得所需的确切信息。您不能针对已经运行的命令执行此操作。

[0]%time sleep 20


评论


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

– lrkwz
2012年11月21日在22:56



#7 楼

$ 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♦
19年6月20日在15:05

#8 楼

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

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

其中13494是您的进程的pid

#9 楼

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

评论


在我看来,这是mattdm已经提到的一个非常细微的变化:date +%s --date =“ now-$(stat -c%X / proc / $$

– Jeff Schaller♦
19年3月28日在17:17

那个在我最小的Alpine docker实例上不适合我,所以我写了这个

– Shardj
19年3月28日在17:31

#10 楼

一个方便的函数,基于“ ps -o etime =“和” bc“,有助于进行数学运算和
左补零数字。

给它pid并获取运行时间。

function running_time (){
  # correct up to 100 days! #08:28:40 #53:32 #15-01:23:00
  p= ; i=$(ps -o etime= $p) ; i=$(echo $i) ;

  len=${#i}
  [[ $len == 5  ]] && i="00-00:$i" ; [[ $len == 8  ]] && i="00-$i"
  [[ $len == 10 ]] && i="0$i"

  mins=$(echo ${i:0:2}*24*60+${i:3:2}*60+${i:6:2}|bc)
  echo $mins
}