You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本中捕获/usr/bin/time执行时间并进行数值比较的问题

解决Bash中捕获/usr/bin/time输出并进行浮点数比较的问题

你遇到的核心问题有两个:一是**/usr/bin/time的格式化输出默认会发送到标准错误(stderr),而Bash的命令替换$()只捕获标准输出(stdout),导致变量exptime无法正确获取时间值;二是/usr/bin/time输出的是浮点数**,没法用Bash的整数运算语法(( ))直接比较。另外脚本被额外调用两次,大概率是因为long-command指向了脚本自身,触发了递归执行。下面分步解决:

1. 正确捕获/usr/bin/time的执行时间

/usr/bin/time(注意区别于Bash内置的time命令)会把-f参数指定的格式输出到stderr,所以需要将stderr重定向到stdout,让命令替换能捕获到结果:

# 方法1:如果不需要保留long-command的输出,直接将其输出丢弃
exptime=$(/usr/bin/time -f '%e' long-command >/dev/null 2>&1)

# 方法2:如果需要保留long-command的正常输出,用文件描述符分离两种输出
exec 3>&1  # 先把当前stdout保存到文件描述符3
exptime=$(/usr/bin/time -f '%e' long-command 2>&1 >&3)  # 将time的stderr转stdout,long-command的输出仍到原stdout
exec 3>&-  # 用完关闭文件描述符3

2. 正确进行浮点数比较

Bash的(( ))语法只支持整数运算,而%e输出的是带小数的时间值(比如79.6或80.3),所以需要用bc或awk这类工具处理浮点数比较:

用bc的写法

if echo "$exptime < 80" | bc -l | grep -q 1; then
    echo "OK"
    exit 0
elif echo "$exptime > 80" | bc -l | grep -q 1; then
    echo "NOK"
    exit 1
else
    echo "error"
    exit 2  # 建议给error状态码,方便后续脚本判断
fi

用awk的写法(更简洁)

# 直接通过awk完成判断和输出
awk -v time="$exptime" '
BEGIN {
    if (time < 80) {
        print "OK"; exit 0
    } else if (time > 80) {
        print "NOK"; exit 1
    } else {
        print "error"; exit 2
    }
}'

# 或者把判断逻辑整合到脚本的条件分支里
if awk -v t="$exptime" 'BEGIN{exit !(t < 80)}'; then
    echo "OK"
    exit 0
elif awk -v t="$exptime" 'BEGIN{exit !(t > 80)}'; then
    echo "NOK"
    exit 1
else
    echo "error"
    exit 2
fi

3. 解决脚本被额外调用两次的问题

如果你的long-command就是当前脚本(比如写的是./My.sh),会触发递归调用,导致脚本多次执行。解决方法:

  • 确认long-command是你实际要测试的目标命令,而非脚本自身;
  • 如果确实需要测试脚本自身,添加递归保护逻辑:
# 脚本开头添加递归检测
if [[ -n "$MY_SCRIPT_RUNNING" ]]; then
    # 这里放脚本的核心业务逻辑,比如模拟耗时操作
    sleep $((RANDOM % 100))
    exit 0
fi
export MY_SCRIPT_RUNNING=1

# 再执行time命令捕获时间
exptime=$(/usr/bin/time -f '%e' "$0" >/dev/null 2>&1)

完整示例脚本

#!/bin/bash

# 递归保护(如果要测试脚本自身的话)
if [[ -n "$MY_SCRIPT_RUNNING" ]]; then
    # 模拟核心业务逻辑,比如随机耗时0-99秒
    sleep $((RANDOM % 100))
    exit 0
fi
export MY_SCRIPT_RUNNING=1

# 捕获执行时间
exptime=$(/usr/bin/time -f '%e' "$0" >/dev/null 2>&1)

# 浮点数比较并输出结果
if awk -v t="$exptime" 'BEGIN{exit !(t < 80)}'; then
    echo "OK"
    exit 0
elif awk -v t="$exptime" 'BEGIN{exit !(t > 80)}'; then
    echo "NOK"
    exit 1
else
    echo "error"
    exit 2
fi

内容的提问来源于stack exchange,提问作者TimSO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 12:14:08