时间命令的自定义格式


71

我想在bash脚本中使用time命令来计算脚本的经过时间,并将其写入日志文件。我只需要实时,而不需要用户和sys。还需要一个体面的格式。例如00:00:00:00(与标准输出不同)。我感谢任何建议。

预期的格式应为00:00:00.0000(毫秒)[小时]:[分钟]:[秒]。[毫秒]

我已经有3个脚本了。我看到了这样的例子:

{ time { # section code goes here } } 2> timing.log

但是我只需要实时,而不需要用户和sys。还需要一个体面的格式。例如00:00:00:00(不像标准输出)。

换句话说,我想知道如何将时间输出变成更易于处理的东西。


1
新的bash版本(> = 4.2)确实printf为此提供了语法:printf -v TimeStamp "%(%s)T" -1printf "%(%a %d %b %Y %T)T\n" $TimeStamp值可以是-1:现在,-2:bash会话的开始,Integer:Unix时间戳
F. Hauri,2013年

1
对于经过的时间(在Linux下),以纳秒为单位,我编写了一个函数。你可以在这里找到解释。
F. Hauri

Answers:


89

您可以使用该date命令获取要进行计时的工作之前和之后的当前时间,并计算出这样的时差:

#!/bin/bash

# Get time as a UNIX timestamp (seconds elapsed since Jan 1, 1970 0:00 UTC)
T="$(date +%s)"

# Do some work here
sleep 2

T="$(($(date +%s)-T))"
echo "Time in seconds: ${T}"

printf "Pretty format: %02d:%02d:%02d:%02d\n" "$((T/86400))" "$((T/3600%24))" "$((T/60%60))" "$((T%60))""

注意: $((...))可以用于bash中的基本算术-注意:请不要在减号前放置空格-因为这可能被解释为命令行选项。

另请参阅:http : //tldp.org/LDP/abs/html/arithexp.html

编辑:
此外,您可能想看看sed来从time生成的输出中搜索和提取子字符串。

编辑:

以毫秒为单位计时的示例(实际上是纳秒,但在此处被截断为毫秒)。您的版本date必须支持该%N格式,并且bash应该支持大量数字。

# UNIX timestamp concatenated with nanoseconds
T="$(date +%s%N)"

# Do some work here
sleep 2

# Time interval in nanoseconds
T="$(($(date +%s%N)-T))"
# Seconds
S="$((T/1000000000))"
# Milliseconds
M="$((T/1000000))"

echo "Time in nanoseconds: ${T}"
printf "Pretty format: %02d:%02d:%02d:%02d.%03d\n" "$((S/86400))" "$((S/3600%24))" "$((S/60%60))" "$((S%60))" "${M}"

免责声明:
我的原始版本说

M="$((T%1000000000/1000000))"

但这已被删除,因为它显然对某些人不起作用,而据报道新版本对某些人无效。我不同意这一点,因为我认为您只需要使用其余部分,而已被淘汰。
选择适合您的东西。


似乎不正确:以秒为单位的时间:46(确定),漂亮格式:00:00:00:46(错误)。使用时间命令:真实0m46.018s用户0m7.630s sys 0m1.190s
John Doe 2010年

嗯,我不太确定00:00:00:00是什么意思– 我猜这意味着[天]:[小时]:[分钟]:[秒]?这就是它所显示的内容,但是您可以随意调整代码以计算所需的内容。

错字的借口。假设为00:00:00.0000(毫秒)[小时]:[分钟]:[秒]。[毫秒]
John Doe 2010年

1
至少对我来说,问题在于它不能与使用模的线配合使用。在不同版本的Linux上的多个版本的bash上运行时,出现以下错误:bash:T%1000000000T:值对于基数太大(错误令牌为“ 1000000000T”)。
mmrobins

1
“对于基本错误而言,值太大”的原因是,将以0开头的数字解释为八进制数字,而T有时以0开头,但不是有效的八进制数字。指定基数10可以避免此问题,方法是删除开头的0:today =“ $(((10#$ today))”。另请参阅fahdshariff.blogspot.nl/2012/08/…–莫里兹
·汉森

46

要使用内置的Bashtime而不是/bin/time您可以设置此变量:

TIMEFORMAT='%3R'

它将输出如下所示的实时时间:

5.009

要么

65.233

该数字指定精度,范围为0到3(默认值)。

您可以使用:

TIMEFORMAT='%3lR'

得到看起来像这样的输出:

3m10.022s

l(ELL)给出了一个长格式。


46

手册页中获取时间

  1. 可能有一个内置的shell称为time,请通过指定避免这种情况 /usr/bin/time
  2. 您可以提供格式字符串,格式选项之一是经过的时间-例如 %E

    /usr/bin/time -f'%E' $CMD

例:

$ /usr/bin/time -f'%E' ls /tmp/mako/
res.py  res.pyc
0:00.01

6
这就是为什么命令:time -f'%E'不起作用,但是/ usr / bin / time -f'%E'可以正常工作的原因。Thx
John Doe 2010年

5
在OS X上,time没有-f标志。您可以通过使用brewbrew install coreutils)安装coreutils然后再使用/usr/local/bin/gtime来解决此问题。
CousinCocaine 2014年

30

使用bash内置变量SECONDS。每次引用该变量时,它将返回自脚本调用以来所经过的时间。

例:

echo "Start $SECONDS"
sleep 10
echo "Middle $SECONDS"
sleep 10
echo "End $SECONDS"

输出:

Start 0
Middle 10
End 20

3

不太确定您要问什么,您是否尝试过:

time yourscript | tail -n1 >log

编辑:好的,所以您知道如何超时,您只想更改格式。如果您描述了所需的格式,将会有所帮助,但是可以尝试以下操作:

time -p script

这会将输出更改为每行一次(以秒为单位)(带小数点)。您只需要实时,而不是其他两个,因此要获得使用的秒数:

time -p script | tail -n 3 | head -n 1

我想将其包含在脚本中。
约翰·多伊

是的,如果这是明确的,那么我不会指出它需要澄清。为什么不使用两个脚本,一个调用另一个脚本?
安德鲁(Andrew)2010年

因为我已经有3个脚本了。我看到了这样的示例:{time {#部分代码在这里}} 2> Timing.log但是我只需要实时,而不需要用户和sys。还需要一个体面的格式。例如00:00:00:00(与标准输出不同)。
约翰·多伊

好的,所以您已经知道如何安排时间,因此这只是您问题中不必要的混乱。您是否真的想知道如何将时间输出转换为更容易处理的内容,例如秒数?
安德鲁(Andrew)2010年

是的,我想知道如何将时间输出变成更易于处理的东西。
约翰·多伊

0

接受的答案给了我这个输出

# bash date.sh
Time in seconds: 51
date.sh: line 12: unexpected EOF while looking for matching `"'
date.sh: line 21: syntax error: unexpected end of file

这就是我解决问题的方式

#!/bin/bash

date1=$(date --date 'now' +%s) #date since epoch in seconds at the start of script
somecommand
date2=$(date --date 'now' +%s) #date since epoch in seconds at the end of script
difference=$(echo "$((date2-$date1))") # difference between two values
date3=$(echo "scale=2 ; $difference/3600" | bc) # difference/3600 = seconds in hours
echo SCRIPT TOOK $date3 HRS TO COMPLETE # 3rd variable for a pretty output.
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.