【发布时间】:2010-12-16 06:10:37
【问题描述】:
所以bash内置的时间函数应该以这种格式输出
real 0m0.002s
user 0m0.001s
sys 0m0.000s
我想以毫秒为单位节省用户时间,例如 001 有什么干净的方法可以做到这一点?
【问题讨论】:
所以bash内置的时间函数应该以这种格式输出
real 0m0.002s
user 0m0.001s
sys 0m0.000s
我想以毫秒为单位节省用户时间,例如 001 有什么干净的方法可以做到这一点?
【问题讨论】:
干净的方法是使用TIMEFORMAT shell 变量只打印用户信息。 (man bash 了解更多详情。)
然后,您当然需要从中捕获输出。这是不可能从管道中完成的,因为它是由 shell 在内部完成的,但是您可以在子 shell 中运行它,并且输出将转到标准错误。但是你必须以某种方式将命令的输出重定向到其他地方。在这里,我只是将其丢弃,但存在许多其他可能性,具体取决于您需要做什么。然后你需要将d.ddd 转换成dddd。只需删除句号即可。
(TIMEFORMAT="%U"; time ls > /dev/null) |& tr -d .
如果您愿意,可以添加| sed s/^0*// 以消除前导零。
%R 将给出实时的 %S 系统时间。您可以使用例如更改精度%6U 来获得微秒,尽管大多数系统不会接近那么准确。
man bash 获取有关重定向的帮助。 man tr 和 man sed 获取有关如何使用它们的帮助。
【讨论】:
tr,一旦你有foo="0.00X",你可以使用参数扩展并输出${foo#*.}来得到00X。无论如何,对 TIMEFORMAT 变量的调用很好,以前从未见过。
TIMEFORMAT - 比我打算做的(虽然很简单)sed 脚本好得多。
Bash 的 time 内置函数有点难以捕获,因为它具有特殊处理,因此它可以返回整个管道的处理时间,例如 time ls -l | sort | uniq,而不仅仅是我的 ls -l 命令的处理时间。例子。
捕获只是时间输出的最佳方法是以下重定向技术:
exec 3>&1 4>&2
foo=$( { time some_command 1>&3 2>&4; } 2>&1 ) # change some_command
exec 3>&- 4>&-
此时,如果您要访问 echo "$foo",您会看到类似
real 0m0.013s
user 0m0.004s
sys 0m0.007s
现在要获得其中的 004 部分,您有很多选择:sed、awk 或直接 bash 来命名前 3 名。我个人最喜欢的是 awk,它看起来像这样:
foo=$({ time some_command 1>&3 2>&4;} 2>&1 | awk -F'[s.]' '/user/{print $3}')
现在,如果您要访问 echo "$foo",您会看到 004 所需的内容
【讨论】:
使用 bash 的内置字符串通配符,您可以执行以下操作:
output="real 0m0.002s
user 0m0.001s
sys 0m0.000s"
#get everything to the right of first "*user "
user=${output#*user }
#get everything to the left of the first "s*"
user=${user%%s*}
#get everythig to let left of "m*"
min=${user%%m*}
#get everything to the right of "*m" and left of ".*"
sec=${user#*m}
sec=${sec%%.*}
#get everything to the right of "*."
usec=${user#*.}
time=$[$usec + $sec * 1000 + $min * 60000]
结果运行bash -x
+ output='real 0m0.002s
user 0m0.001s
sys 0m0.000s'
+ user='0m0.001s
sys 0m0.000s'
+ user=0m0.001
+ min=0
+ sec=0.001
+ sec=0
+ usec=001
+ time=1
【讨论】:
time 的输出转换为$output。