Linux 操作系统,一些比较关键的命令和方法

install-casaos.sh: line 414: printf: 40.96: invalid number

PHPer 2025-09-22 7 0 0
 Starting network speed test (max 60 s) from URL: https://github.com/IceWhaleTech/CasaOS-CLI/releases/download/v0.4.4-3-alpha1/linux-amd64-casaos-cli-v0.4.4-3-alpha1.tar.gz
? Real-time download speed will be shown below:
install-casaos.sh: line 414: printf: 40.96: invalid number
Get_Network_Speed() {
    local TEST_URL="${1:-https://speed.hetzner.de/100MB.bin}"  # 默认为稳定测速文件,可替换
    local TEMP_FILE="/tmp/speedtest_$$.bin"
    local START_TIME END_TIME DURATION FILE_SIZE SIZE_MB
    local MAX_TEST_TIME=60  # 最长测速时间(秒),可自行调整
    local TIMEOUT_CMD="timeout $MAX_TEST_TIME"
    # 清理临时文件
    trap 'rm -f "$TEMP_FILE"' EXIT
    echo "⏬ Starting network speed test (max $MAX_TEST_TIME s) from URL: $TEST_URL"
    echo "? Real-time download speed will be shown below:"
    START_TIME=$(date +%s.%N)
    # 后台启动 wget 下载
    $TIMEOUT_CMD wget -q --show-progress=no -O "$TEMP_FILE" "$TEST_URL" >/dev/null 2>&1 &
    local WGET_PID=$!
    local PREV_SIZE=0
    local PREV_TIME=$START_TIME
    local SPEED_UPDATE_INTERVAL=1  # 每隔1秒更新一次速度显示
    # === 实时监测下载速度 ===
    while kill -0 "$WGET_PID" 2>/dev/null; do
        sleep $SPEED_UPDATE_INTERVAL
        local CURRENT_TIME=$(date +%s.%N)
        local CURRENT_SIZE=$(wc -c < "$TEMP_FILE" 2>/dev/null || echo 0)
        local ELAPSED=$(echo "$CURRENT_TIME - $PREV_TIME" | bc -l)
        if (( $(echo "$ELAPSED >= $SPEED_UPDATE_INTERVAL" | bc -l) )) && [ "$(echo "$ELAPSED > 0" | bc -l)" -eq 1 ]; then
            local DIFF_SIZE=$((CURRENT_SIZE - PREV_SIZE))
            if [ "$DIFF_SIZE" -gt 0 ]; then
                local SIZE_MB=$(echo "scale=2; $DIFF_SIZE / 1048576" | bc -l)
                local SPEED_MB_S=$(echo "scale=2; $SIZE_MB / $ELAPSED" | bc -l)
                local SPEED_KB_S=$(echo "scale=0; $SPEED_MB_S * 1024" | bc -l)
                # 动态刷新当前速度(带单位,自动选择 MB/s 或 KB/s 更直观)
                if (( $(echo "$SPEED_MB_S >= 0.1" | bc -l) )); then
                    printf "\r? Current Speed: %.2f MB/s" "$SPEED_MB_S"
                else
                    printf "\r? Current Speed: %d KB/s" "$SPEED_KB_S"
                fi
            fi
            PREV_SIZE=$CURRENT_SIZE
            PREV_TIME=$CURRENT_TIME
        fi
    done
    # 等待 wget 进程结束(可能是被 timeout 中断的)
    wait "$WGET_PID" 2>/dev/null || true
    END_TIME=$(date +%s.%N)
    DURATION=$(echo "$END_TIME - $START_TIME" | bc -l)
    # 避免除零
    if (( $(echo "$DURATION <= 0" | bc -l) )); then
        DURATION=0.1
    fi
    FILE_SIZE=$(wc -c < "$TEMP_FILE" 2>/dev/null || echo 0)
    if [ "$FILE_SIZE" -eq 0 ]; then
        echo -e "
❌ ❗ No data downloaded or download failed."
        return 1
    else
        SIZE_MB=$(echo "scale=2; $FILE_SIZE / 1048576" | bc -l)
        DOWNLOAD_SPEED_MB_S=$(echo "scale=2; $SIZE_MB / $DURATION" | bc -l)
        # 最终结果输出
        local FORMATTED_AVG=$(printf "%.2f" "$DOWNLOAD_SPEED_MB_S")
        echo -e "
✅ Downloaded $(printf "%.2f" "$SIZE_MB") MB in $(printf "%.2f" "$DURATION") s → Avg Speed: ${FORMATTED_AVG} MB/s"
    fi
    return 0
}

20250922 1133

你遇到的错误:

```

install-casaos.sh: line 414: printf: 40.96: invalid number

```

是因为 **`printf` 在某些 shell 环境(尤其是 `dash` 或严格模式下的 `bash`)中不支持浮点数格式化为参数**。虽然 `%.2f` 是合法的格式符,但当你把一个浮点数(如 `40.96`)作为参数传给 `printf` 时,某些 `printf` 实现会报错,因为它期望整数。

此外,在你的代码中:

```bash

printf "\r? Current Speed: %.2f MB/s" "$SPEED_MB_S"

```

```bash

printf "%.2f" "$DOWNLOAD_SPEED_MB_S"

```

都可能触发这个错误,特别是在使用了 `busybox` 版本或非 GNU 环境的系统上。

---

### ✅ 解决方案:改用 `awk` 进行浮点数格式化

`awk` 是处理浮点运算和格式化的可靠工具,不受 `printf` 内建限制影响。

---

### ✅ 修改后的函数(已修复)

Get_Network_Speed() {
    local TEST_URL="${1:-https://speed.hetzner.de/100MB.bin}"
    local TEMP_FILE="/tmp/speedtest_$$.bin"
    local MAX_TEST_TIME=60
    local TIMEOUT_CMD="timeout $MAX_TEST_TIME"

    # 清理临时文件
    trap 'rm -f "$TEMP_FILE"' EXIT

    echo "⏬ Starting network speed test (max $MAX_TEST_TIME s) from URL: $TEST_URL"
    echo "? Real-time download speed will be shown below:"

    local START_TIME=$(date +%s.%N)

    # 启动下载
    $TIMEOUT_CMD wget -q --show-progress=no -O "$TEMP_FILE" "$TEST_URL" >/dev/null 2>&1 &
    local WGET_PID=$!

    local PREV_SIZE=0
    local PREV_TIME=$START_TIME
    local SPEED_UPDATE_INTERVAL=1

    # === 实时监测速度 ===
    while kill -0 "$WGET_PID" 2>/dev/null; do
        sleep $SPEED_UPDATE_INTERVAL

        local CURRENT_TIME=$(date +%s.%N)
        local CURRENT_SIZE=$(wc -c < "$TEMP_FILE" 2>/dev/null || echo 0)

        local ELAPSED=$(echo "$CURRENT_TIME - $PREV_TIME" | bc -l)

        if (( $(echo "$ELAPSED >= $SPEED_UPDATE_INTERVAL" | bc -l) )) && [ "$(echo "$ELAPSED > 0" | bc -l)" -eq 1 ]; then
            local DIFF_SIZE=$((CURRENT_SIZE - PREV_SIZE))

            if [ "$DIFF_SIZE" -gt 0 ]; then
                local SIZE_MB=$(echo "scale=2; $DIFF_SIZE / 1048576" | bc -l)
                local SPEED_MB_S=$(echo "scale=3; $SIZE_MB / $ELAPSED" | bc -l)

                # 使用 awk 格式化输出,避免 printf 浮点错误
                if (( $(echo "$SPEED_MB_S >= 0.1" | bc -l) )); then
                    printf "\r? Current Speed: %s MB/s" "$(echo "$SPEED_MB_S" | awk '{printf "%.2f", $1}')"
                else
                    local SPEED_KB_S=$(echo "$SPEED_MB_S * 1024" | bc -l)
                    printf "\r? Current Speed: %s KB/s" "$(echo "$SPEED_KB_S" | awk '{printf "%.0f", $1}')"
                fi
            fi

            PREV_SIZE=$CURRENT_SIZE
            PREV_TIME=$CURRENT_TIME
        fi
    done

    wait "$WGET_PID" 2>/dev/null || true

    local END_TIME=$(date +%s.%N)
    local DURATION=$(echo "$END_TIME - $START_TIME" | bc -l)

    # 防止除零
    if (( $(echo "$DURATION <= 0.01" | bc -l) )); then
        DURATION=0.1
    fi

    local FILE_SIZE=$(wc -c < "$TEMP_FILE" 2>/dev/null || echo 0)
    if [ "$FILE_SIZE" -eq 0 ]; then
        echo -e "\n❌ ❗ No data downloaded or download failed."
        return 1
    else
        local SIZE_MB=$(echo "scale=2; $FILE_SIZE / 1048576" | bc -l)
        local AVG_SPEED=$(echo "scale=3; $SIZE_MB / $DURATION" | bc -l)

        # 最终结果也用 awk 格式化
        local FORMATTED_SIZE=$(echo "$SIZE_MB" | awk '{printf "%.2f", $1}')
        local FORMATTED_DURATION=$(echo "$DURATION" | awk '{printf "%.2f", $1}')
        local FORMATTED_AVG=$(echo "$AVG_SPEED" | awk '{printf "%.2f", $1}')

        echo -e "\n✅ Downloaded ${FORMATTED_SIZE} MB in ${FORMATTED_DURATION} s → Avg Speed: ${FORMATTED_AVG} MB/s"
    fi

    return 0
}

### ✅ 主要修改点说明: ...

立即注册
更新于:2025-09-22 11:36:12
    您需要登录后才可以评论。 立即注册
    相关内容

    linux vim中不小心按了#号,结果printf就变成这个颜色了,怎么给变回来啊,求...

    Chrome浏览器:The request client is not a secure context and the reso...

    python and shell

    为什么使用副 shell 脚本生成 Python 文件

    Linux的工具应用

    ubuntu24.04 最好的输入法是什么?

    Windows的压缩卷或者叫磁盘分区Resize的工具MiniTool

    让ubuntu更像Windows

    视频播放器

    GParted - linux下的硬盘 resize工具。不用重新安装系统。

    ​elementary OS 8.0.1 和Nitrux OS 的磁力链接,manjaro 的官网,feren ...

    列出所有在维护的Linux Desktop

    exFAT 我去看看,走先,去win11了

    在Linux上使用像微软拼音一样好用的输入法​​

    国外的linux用户是如何平替windows的那些软件的

    mysqli的基本使用

    推荐内容

    怎样使用V2Ray代理和SSTap玩如魔兽世界/绝地求生/LOL台服/战地3/黑色沙漠/彩...

    sstap游戏代理教程 从此玩如魔兽世界/绝地求生/LOL台服/战地3/黑色沙漠/彩虹六...

    BT磁力搜索网站汇总和找不到的资源

    什么是磁力链接,您如何使用?

    Z-Library:全球最大的数字图书馆/含打不开的解决方案/镜像

    使用V2Ray的mKCP协议加速游戏

    v2rayN已停止工作

    【车险课堂】什么是无赔款优待系数ncd,你“造”吗?