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

Bash脚本远程执行命令进度条异常问题求助

修复带百分比进度条的多机器SSH执行脚本

核心问题分析

添加进度条后脚本故障,大概率是SSH会话占用标准输入,或者循环执行方式导致子进程变量隔离,也可能是进度条输出和远程命令输出冲突。以下是针对这类问题的通用修复方案,同时保留逐台执行+进度条的功能。

修复后的完整脚本

#!/bin/bash

# 检查参数合法性
if [ $# -ne 1 ]; then
    echo "用法: $0 <IP列表文件路径>"
    exit 1
fi

IP_LIST="$1"
# 统计总机器数(过滤空行)
TOTAL=$(grep -v '^$' "$IP_LIST" | wc -l)
CURRENT=0

# 封装远程执行逻辑
function1() {
    local target_ip="$1"
    # 远程执行的命令集合,按需修改
    ssh -n "$target_ip" << 'REMOTE_CMDS'
        # 示例命令:替换成你实际需要执行的操作
        echo "当前主机: $(hostname)"
        uptime
        free -h
REMOTE_CMDS
    # 可选:将远程输出写入日志文件,避免干扰进度条
    # ssh -n "$target_ip" << 'REMOTE_CMDS' >> "log_${target_ip}.txt"
    #     ...
    # REMOTE_CMDS
}

# 进度条渲染函数
render_progress() {
    local curr=$1
    local total=$2
    local percent=$(( curr * 100 / total ))
    # 用回车覆盖当前行,实现单行进度条
    printf "\r[%-50s] %d%% 已完成: %d/%d" \
        $(printf "#%.0s" $(seq 1 $(( percent / 2 )))) \
        $percent $curr $total
}

# 逐台执行主逻辑
while IFS= read -r ip; do
    # 跳过空行和注释行(如果有)
    [[ -z "$ip" || "$ip" =~ ^# ]] && continue
    
    CURRENT=$(( CURRENT + 1 ))
    # 执行远程命令
    function1 "$ip"
    # 更新进度条
    render_progress "$CURRENT" "$TOTAL"
done < "$IP_LIST"

# 最后换行,避免后续输出和进度条重叠
echo -e "\n所有主机执行完成"

关键修复点说明

  1. ssh -n 参数:强制SSH不读取标准输入,避免和read命令争抢IP列表的输入流——这是最常见的故障诱因,不加-n的话,SSH会把剩余的IP行当作输入,导致循环提前终止。
  2. 避免管道子进程陷阱:用while read ... < "$IP_LIST"替代cat "$IP_LIST" | while read ...,后者会创建子进程,导致CURRENT变量无法在父进程中更新,进度条永远停留在0%。
  3. 进度条行覆盖:用printf "\r"实现单行刷新,避免进度条刷屏;同时用%-50s固定进度条长度,保证显示整齐。
  4. 远程命令隔离:用<< 'REMOTE_CMDS'(单引号包裹分界符),防止本地变量被远程Shell解析,避免意外错误。
  5. 空行/注释过滤:添加[[ -z "$ip" || "$ip" =~ ^# ]] && continue,跳过IP列表中的空行和注释行,避免无效SSH连接。

验证方法

  • 先注释掉进度条相关代码(render_progress调用和函数),确认核心SSH执行逻辑正常;
  • 再恢复进度条代码,测试逐台执行时的百分比显示是否正常,无输出错乱或提前终止问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 03:37:34