我有这个愚蠢的脚本来跟踪我的 cron 作业的执行时间,以了解脚本何时启动和停止。
start=$(date +'%Y-%m-%d %H:%M:%S') # This line converts to 2019-09-10 00:50:48
echo "$start"
./actual_script_runs_here
stop=$(date +'%Y-%m-%d %H:%M:%S')
echo "$stop"
Run Code Online (Sandbox Code Playgroud)
这种方法有效。但我必须计算自己运行脚本所花费的时间。是否可以在 bash 中计算这个?
或者我可以使用time
命令。但它返回了 3 个不同的时间,有 3 个新行。我更愿意在一行中看到该时间结果和我的脚本结果。
der*_*ert 11
您可以使用date +%s
获取可以轻松计算的日期格式(自 1970 年 1 月 1 日 00:00:00Z 以来的秒数 [带警告])。您还可以使用date -d "$start" +%s
. 这并不理想,不仅是由于转换回来时的 DST 问题,而且如果有人在您的程序运行时更改了时间,或者如果 ntp 之类的东西这样做了,那么您会得到错误的答案。可能是一个非常错误的。
闰秒会给你一个稍微错误的答案(差一秒)。
不幸的是,检查时间的源代码,它似乎time
遇到了使用挂钟时间(而不是“单调”时间)的相同问题。幸运的是,Perl 几乎无处不在,并且可以访问单调定时器:
start=$(perl -MTime::HiRes=clock_gettime,CLOCK_MONOTONIC -E 'say clock_gettime(CLOCK_MONOTONIC)')
Run Code Online (Sandbox Code Playgroud)
这将获得自过去任意点以来的秒数(在 Linux 上,自启动以来,不包括机器挂起的时间)。即使更改时钟,它也会计算秒数。由于在 shell 中处理实数(非整数)有些困难,因此您可以在 Perl 中完成整个操作:
start=$(perl -MTime::HiRes=clock_gettime,CLOCK_MONOTONIC -E 'say clock_gettime(CLOCK_MONOTONIC)')
Run Code Online (Sandbox Code Playgroud)
我将其命名为“单调时间”;它就像“时间”一样使用(没有自己的任何参数)。所以:
$ monotonic-time sleep 5
5.001831 # appeared ?5s later
$ monotonic-time fortune -s
Good news is just life's way of keeping you off balance.
0.017800
Run Code Online (Sandbox Code Playgroud)
ilk*_*chu 11
在 Bash 中,您还可以使用魔法变量SECONDS
:
SECONDS
每次引用此参数时,都会返回自调用 shell 以来的秒数。
所以:
bash -c 'a=$SECONDS; sleep 5; b=$SECONDS; printf "%d seconds passed\n" "$((b-a))"'
Run Code Online (Sandbox Code Playgroud)
输出5 seconds passed
。
SECONDS
虽然只有整秒的粒度,但date +"... %S"
. 使用 GNU 日期,您可以使用%N
with%s
获取以纳秒为单位的时间时间。
a=$(date +%s%N)
sleep 1.234
b=$(date +%s%N)
diff=$((b-a))
printf "%s.%s seconds passed\n" "${diff:0: -9}" "${diff: -9:3}"
Run Code Online (Sandbox Code Playgroud)
印刷:
1.237 seconds passed
Run Code Online (Sandbox Code Playgroud)
Bash 无法对浮点数进行算术运算,因此您需要使用外部实用程序进行计算,或者像我上面所做的那样以小于秒的单位进行计算。(这些数字不适合 32 位,因此这可能不适用于 32 位系统。即使在 32 位系统上,我也不确定 Bash 是否使用 64 位进行算术。)
SECONDS
如果在测量期间修改系统时间也会出错,但实际上您应该只在启动期间设置一次时间,然后让 NTP 调整时钟以保持准时。