如同如何查看一个进程已经运行了多长时间?,我试图使用 BusyBox 和sh
(而不是bash
)获取嵌入式 Linux 系统中进程的运行时间(以秒为单位)。不同之处在于我想要纯秒,而不是 mm:ss 格式。
我可以从结果中解析它,ps
但无法expr
从 mm:ss 转换为秒。使用set -vx
帮助调试我可以看到有效的expr
命令,但它因语法错误而失败。复制并粘贴它效果很好。
运行此命令以进行附加诊断后:
root@embedded:~# set -vx
我输入:
root@embedded:~# $(/opt/bin/busybox ps -o pid,etime,time | grep 1156 | sed "s/ *[0-9]\+ \+\([0-9]\+\):\([0-9]\+\) .*/\/opt\/bin\/busybox expr \1 \\\* 60 + \2/")
并得到这样的回应:
$(/opt/bin/busybox ps -o pid,etime,time | grep 1156 | sed "s/ *[0-9]\+ \+\([0-9]\+\):\([0-9]\+\) .*/\/opt\/bin\/busybox expr \1 \\\* 60 + \2/")
+ /opt/bin/busybox ps -o pid,etime,time
+ grep 1156
+ sed s/ *[0-9]\+ \+\([0-9]\+\):\([0-9]\+\) .*/\/opt\/bin\/busybox expr \1 \\* 60 + \2/
+ /opt/bin/busybox expr 2 \* 60 + 03
expr: syntax error
root@embedded:~#
我还尝试了多层\
转义以及''
.
我需要做什么才能将转义*
传递到expr
命令行?
答案1
eval
可能对这个案子有帮助...
~ $ $(echo expr 1 \\* 2)
+ echo expr 1 \* 2
+ expr 1 \* 2
expr: syntax error
~ $ eval $(echo expr 1 \\* 2)
+ echo expr 1 \* 2
+ eval expr 1 \* 2
+ expr 1 * 2
2
但在 Linux 上查找可能会更好/proc/$pid/stat
。
pid=1155
hz=$(getconf CLK_TCK)
uptime=$(awk '{print $1}' < /proc/uptime)
starttime=$(awk '{print $22}' < /proc/$pid/stat)
echo $(( ${uptime%.*} - $starttime / $hz ))
如果/usr/bin/getconf
不可用,您需要查找系统的CLK_TCK
(或USER_HZ
)值。我认为大多数情况下你可以将其假设为 100。
答案2
尴尬的是,我似乎并没有像我想象的那样进行彻底的测试。事实证明,修改我在问题中发布的内容以仅包含两个转义符 ( \\*
) 可以使其正常工作。
root@embedded:~# $(/opt/bin/busybox ps -o pid,etime | sed -n "s/ *1155 \+\([0-9]\+\):\([0-9]\+\).*/expr \1 \\* 60 + \2/p")
$(/opt/bin/busybox ps -o pid,etime | sed -n "s/ *1155 \+\([0-9]\+\):\([0-9]\+\).*/expr \1 \\* 60 + \2/p")
+ /opt/bin/busybox ps -o pid,etime
+ sed -n s/ *1155 \+\([0-9]\+\):\([0-9]\+\).*/expr \1 \* 60 + \2/p
+ expr 293 * 60 + 54
17634
请注意,我还将该方法集成到了grep
(全局sed
-n 's///p'
no 打印,然后p匹配时打印)。
感谢@yaegashi 让我再试\\
一次......
答案3
假设进程是16752(你似乎能够弄清楚)
expr $(date +%s) - $(stat -c %Y /proc/16752/environ )
在哪里
date +%s
是自纪元以来的第二个当前日期stat -c %Y /proc/16752/environ
是 /proc/16752/environ 的“创建日期”,即 proc #16752 启动的时刻
编辑:
也许
/proc/$PID/environ
是错误的伪文件,/proc/$PID/exe
应该改用。如果主机上的时间发生变化,则结果来自
ps -p $PID -h -o etime
和时间戳/proc/$PID/exe
可能都是错误的。 (不确定如何检查)。
答案4
这是一个 awk 脚本,它将把 0-00:00:00 输出转换为秒。它是这样使用的...
ps -eo pid,time,user,comm | awk '{print $1"|"$2"|"$3"|"$4$5$6$7$8$9$10}' | awk -f _os_return_process_time_in_seconds.awk
这是脚本。只是为了其他目的而写的。可能仍有问题。
BEGIN {
FS="|"
}
{
pid=$1
time=$2
user=$3
comm=$4
split_count=split($2,days_array,"\-")
if ( split_count == 2 ) {
days=days_array[1]
hr_min_sec=days_array[2]
}
else {
days=0
hr_min_sec=days_array[1]
}
split_count=split(hr_min_sec,hr_min_sec_array,":")
if ( split_count == 3 ) {
hours=hr_min_sec_array[1]
minutes=hr_min_sec_array[2]
seconds=hr_min_sec_array[3]
}
else if ( split_count == 2 ) {
hours=0
minutes=hr_min_sec_array[1]
seconds=hr_min_sec_array[2]
}
else if ( split_count == 1 ) {
hours=0
minutes=0
seconds=hr_min_sec_array[1]
}
total_seconds=(days*24*60*60)+(hours*60*60)+(minutes*60)+(seconds)
print pid"|"total_seconds"|"user"|"comm
}