日常跑脚本、编译、仿真时,我们经常需要知道一条命令到底跑了多久。
Bash 和 csh/tcsh 都提供了内建的 time,但输出格式和定制方式差别很大。
这篇文章会总结两者的用法,并重点给出如何输出 ?m?s(如 1m5s)或 ?:?(如 1:05)这类适合阅读长时间计时的样式。
Bash 的 time 是一个 保留字,可以直接加在管道前面:
输出默认到 stderr:
real:实际经过时间(墙钟时间)
user:用户态 CPU 时间
sys:内核态 CPU 时间
Bash 用 TIMEFORMAT 控制 time 的输出格式。
常用占位符:
| 占位符 | 含义 |
|---|---|
%R | real 时间,秒 |
%U | user 时间,秒 |
%S | sys 时间,秒 |
%P | CPU 占用百分比 |
%lR | real 长格式,如 1m5.003s |
%lU | user 长格式 |
%lS | sys 长格式 |
注意:l 是 小写字母 L,不是数字 1。
?m?s 样式设置:
输出:
%0lR 表示长格式、0 位小数,所以是 1m5s 而不是 1m5.003s。
如果想同时看用户/系统时间:
输出:
?:? 样式(如 1:05)TIMEFORMAT 本身不能直接输出 1:05,因为长格式固定是 1m5s。
如果一定要 分:秒,可以用 SECONDS 或 EPOCHREALTIME 自己算。
方法一:整数秒(SECONDS)
输出:
方法二:高精度(EPOCHREALTIME,Bash 5.0+)
输出:
计时整个管道:
只计时管道中的某一段:
csh/tcsh 也有内建 time,但它是 命令,不是保留字。
用法:
输出类似:
其中 0:05 就是 分:秒 格式,即 ?:? 样式。
这串数字的含义:
| 部分 | 含义 |
|---|---|
%Uu | 用户态 CPU 秒数 |
%Ss | 内核态 CPU 秒数 |
%E | 实际经过时间,格式 h:mm:ss 或 m:ss |
%P | CPU 占用百分比 |
%X+%Dk | 内存占用 |
%I+%Oio | IO 次数 |
%Fpf+%Ww | 缺页/换出 |
csh 用 time 变量控制输出格式。
可以设置成格式字符串:
输出:
也可以设置成 (秒数 格式字符串),实现 超过指定 CPU 秒数才自动打印:
?m?s 样式csh 的 %E 默认输出 ?:?(如 0:05、1:05),而不是 1m5s。
如果非要 1m5s,需要自己后处理。例如:
输出:
注意:csh 的 @ 是算术运算,$total 必须是整数。
仿真工具 VCS 的日志末尾通常有:
这个格式是固定的,VCS 没有选项改成“几分几秒”。
但我们可以用脚本后处理。
?m?s输出:
?:?输出:
| 需求 | Bash | csh / tcsh |
|---|---|---|
| 基本计时 | time command | time command |
| 自定义格式 | TIMEFORMAT | set time = "格式" |
输出 ?m?s | TIMEFORMAT='%0lR' 得到 1m5s | 需自己算,%E 是 1:05 |
输出 ?:? | 需自己算(SECONDS / EPOCHREALTIME) | %E 默认就是 1:05 |
| 计时管道/复合命令 | 支持,用 {} 或 () | 只支持简单命令 |
| 输出目的地 | stderr | stdout |
| 超时自动打印 | 不支持 | set time = ( 秒数 "格式" ) |
推荐:
日常用 Bash:TIMEFORMAT='耗时 %0lR',直接得到 1m5s,简洁明了。
如果习惯 分:秒:Bash 里用 SECONDS 自己算,csh 里直接用 %E。
处理 VCS 日志:用 awk 提取秒数并转换,灵活可控。
长时间命令:优先用 ?m?s 或 ?:?,比纯秒数(如 420.930 seconds)直观得多。
希望这篇总结能帮你在不同 Shell 下都能轻松读出命令的真实耗时。