为什么在 Bash 的 time 前设置 TIMEFORMAT 不生效?
结论
两种写法中的 time 会被 Bash 解析成不同的命令。TIMEFORMAT='%R'; time echo hi 使用 Bash 的 time 保留字,而 TIMEFORMAT='%R' time echo hi 中的 time 被当作普通命令名。题示输出与 GNU time 的默认格式一致,因此第二条命令调用的是外部 GNU time。GNU time 使用自己的格式设置,不读取 Bash 的 TIMEFORMAT。GNU time 输出格式说明
如果只想临时修改这一次 Bash 计时的格式,可以这样写:
( TIMEFORMAT='%R'; time echo hi )
为什么变量赋值的位置会影响结果?
Bash 的 time 是保留字,只有出现在允许识别保留字的位置时,才会启用 Bash 自身的计时功能。Bash 保留字规则
第一种写法中,分号结束了变量赋值命令,后面的 time 位于新命令的开头:
TIMEFORMAT='%R'; time echo hi
赋值直接修改当前 shell 的变量,Bash 随后读取 TIMEFORMAT 来格式化计时结果。由于读取变量的是当前 Bash,这里无需 export。Bash 的 time 与 TIMEFORMAT
第二种写法中,前面的赋值使 Bash 进入简单命令的解析过程:
TIMEFORMAT='%R' time echo hi
这里的 time 成为普通命令名,echo 和 hi 是它的参数。按题示环境,time 解析为外部 GNU time。临时赋值的 TIMEFORMAT 会传入该程序的环境,但 GNU time 不使用这个变量。
怎样只为一次 Bash 计时设置格式?
将赋值和计时放进同一个子 shell:
(
TIMEFORMAT='%R'
time echo hi
)
子 shell 内的 Bash 能读取这个变量,括号结束后,外层 shell 原有的 TIMEFORMAT 设置保持不变。%R 表示经过的实际时间,单位为秒,具体数值取决于运行情况。Bash 手册
如果希望后续计时也使用相同格式,直接在当前 shell 中设置即可:
TIMEFORMAT='%R'
time echo hi
如果要使用外部 GNU time,应该怎样设置?
GNU time 支持 -f 参数和 TIME 环境变量。若其安装路径为 /usr/bin/time,可以使用以下任一种方式:
/usr/bin/time -f '%e' echo hi
TIME='%e' /usr/bin/time echo hi
GNU time 的 %e 表示以秒为单位的经过时间。它与 Bash 的格式占位符不同,不能直接套用 Bash 的 %R。GNU time 手册
排查当前环境时,可以运行:
type -a time
检查结果中是否同时存在 shell keyword 和外部可执行文件,并以实际路径为准。上述 -f '%e' 示例适用于 GNU time;其他系统提供的 time 可能支持不同选项。
备注:内容仅供参考。
