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

优化跨分支Linux机器SSH密钥认证文件传输脚本的问题

批量推送配置文件脚本优化求助

我是公司IT专员,公司多分支服务器使用Linux Fedora 35系统,需要批量向所有机器推送配置文件。我用Fedora 39机器执行任务,已通过Bash脚本完成SSH公钥分发,实现无密码密钥认证访问。

当前编写的文件传输脚本会遍历网关IP列表,对每个网关生成尾段10-22的机器IP,ping通后用rsync传输文件,但部分IP会导致脚本冻结甚至停止。我曾尝试将循环进程放入后台,但仍未解决问题,请教如何调整脚本以实现高效稳定运行。

现有脚本

#!/bin/bash

# Specify the default location for the SSH key
SSH_KEY=/root/.ssh/id_rsa

current_date=$(date +%Y-%m-%d)
source_file="/home/abdulrahman/firefox-redhat-default-prefs.js"
remote_dir="/usr/lib64/firefox/browser/defaults/preferences/"

source_file2="/etc/hosts"
remote_dir2="/etc/"

source_file3="/home/abdulrahman/Tamweely-CA.cer"
remote_dir3="/"

# Function to ping an IP address
ping_ip() {
    local ip=$1
    # Remove non-numeric characters from the IP address
    ip=$(echo "$ip" | tr -cd '[:digit:].')
    # Check if the IP address is empty after cleaning
    if [ -z "$ip" ]; then
        echo "Skipping invalid IP address."
        return
    fi
    ping -W 5 -c 1 "$ip" > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "IP address $ip is up."
    return 0
    else
        echo "IP address $ip is down."
    return 1
    fi
}

send_file(){
    local source_file=$1
    local ip_addr=$2
    local remote_dir=$3

    #scp -l "250" -o "StrictHostKeyChecking=no" "$source_file" "root@$ip_addr:$remote_dir" 
    rsync -avmzPR -e "ssh -o StrictHostKeyChecking=no -o ConnectTimeout=60" --progress "$source_file" "root@$ip_addr:$remote_dir"

    if [ $? -eq 0 ]; then
    echo "File is sent successfully to $ip_addr" | tee -a "/home/abdulrahman/scs/reports/file_report_$current_date.txt"    
    else        
        echo "Failed to send file to $ip_addr" | tee -a "/home/abdulrahman/scs/reports/file_report_$current_date.txt"
    fi      
}


# Specify the path to your text file
IP_FILE="/home/abdulrahman/scs/ip_addresses.txt"
#IP_FILE="/home/abdulrahman/scs/ip_address2.txt"


# Check if the file exists
if [ ! -f "$IP_FILE" ]; then
    echo "Error: File $IP_FILE not found."
    exit 1
fi

# Initialize an array to store background process IDs
#declare -a bg_pids

# Read each line (IP address) from the file and perform an action
while IFS= read -r ip_address; do
    # You can replace the echo statement with the action you want to perform
    for device_ip in ${ip_address%.*}.{10..22}; do 
        if ping_ip "$device_ip"; then
        send_file "$source_file" "$device_ip" "$remote_dir"   
        send_file "$source_file2" "$device_ip" "$remote_dir2"  
        send_file "$source_file3" "$device_ip" "$remote_dir3" 
        #Store the background process ID
            #bg_pids+=($!)  
        fi
    done    
done < "$IP_FILE"

# Wait for all background processes to complete
#for pid in "${bg_pids[@]}"; do
#  wait "$pid"
#done 

IP列表文件(ip_addresses.txt)

192.168.119.1   
192.168.3.1 
192.168.2.1 
192.168.7.1 
192.168.6.1 
192.168.4.1 
192.168.20.1    
192.168.110.1   
192.168.13.1    
192.168.21.1    
172.27.13.1 
192.168.114.1   
172.27.15.1 
172.27.16.1 
172.27.17.1 
172.28.18.1 
172.27.19.1 
172.27.20.1 
172.27.21.1 
172.27.22.1 
172.28.23.1 
172.27.24.1 
172.27.25.1 
172.27.26.1 
172.27.27.1 
172.27.28.1 
172.27.29.1 
172.27.30.1 
172.27.31.1 
172.27.32.1 
172.27.33.1 
172.28.34.1 
172.28.35.1 
172.27.36.1 
172.28.37.1     
172.28.38.1 
172.27.39.1 
172.27.40.1 
172.27.41.1 
172.28.42.1 
172.28.43.1 
172.27.44.1 
172.27.45.1 
172.27.46.1 
172.28.47.1 
172.27.48.1 
172.27.49.1 
172.27.50.1 
172.27.51.1 
172.28.53.1 
172.28.54.1 
172.27.56.1 
172.27.57.1 
172.28.58.1 
172.27.59.1 
172.27.60.1 
172.27.61.1 
172.28.63.1 
172.27.64.1 
172.28.65.1 
172.28.66.1 
172.28.67.1 
172.28.68.1 
172.27.69.1 
172.27.70.1 
172.27.71.1 
172.28.72.1 
172.28.73.1 
172.28.74.1 
172.27.75.1 
172.27.76.1 
172.27.77.1 
172.27.78.1 
172.27.79.1 
172.27.80.1 
172.27.81.1 
172.27.82.1 
172.28.83.1 
172.27.84.1 
172.27.85.1 
172.27.86.1 
172.28.87.1 
172.28.88.1 
172.28.89.1 
172.27.90.1 
172.27.91.1 
172.27.92.1 
172.28.93.1 
172.28.94.1 
172.28.95.1 
172.28.96.1 
172.27.97.1 
172.27.98.1 
172.27.99.1 
172.27.100.1    
172.27.101.1    
172.27.102.1    
172.28.103.1    
172.28.104.1    
172.28.105.1    
172.28.106.1    
172.28.107.1    
172.28.108.1    
172.28.109.1    
172.28.110.1    
172.27.111.1    
172.28.112.1    
172.27.113.1    
172.27.114.1    
172.27.115.1    
172.27.116.1    
172.27.117.1    
172.28.118.1    
172.28.119.1    
172.27.120.1    
172.27.121.1    
172.27.122.1    
172.27.123.1    
172.27.124.1    
172.27.125.1    
172.27.126.1    
172.27.127.1    
172.27.128.1    
172.28.129.1    
172.27.130.1    
172.28.131.1    
172.28.132.1    
172.28.133.1    
172.28.134.1    
172.28.135.1    
172.27.136.1    
172.28.137.1    
172.28.138.1    
172.27.139.1    
172.27.140.1    
172.27.141.1    
172.27.142.1    
172.27.143.1    
172.28.144.1    
172.27.145.1    
172.28.146.1    
172.28.147.1    
172.27.148.1    
172.28.149.1    
172.27.150.1    
172.28.151.1    
172.28.152.1    
172.28.153.1    
172.27.154.1    
172.28.155.1    
172.27.156.1    
172.28.157.1    
172.28.158.1    
172.28.159.1    
172.28.160.1    
172.27.161.1    
172.28.162.1    
172.28.163.1    
172.27.164.1    
172.27.165.1    
172.27.166.1    
172.27.167.1    
172.28.168.1    
172.27.169.1    
172.27.170.1    
172.28.171.1    
172.28.172.1    
172.28.173.1    
172.28.174.1    
172.28.175.1    
172.27.176.1    
172.28.177.1    
172.28.178.1    
172.28.179.1    
172.28.180.1    
172.28.181.1    
172.27.182.1    
172.28.183.1    
172.27.184.1    
172.27.185.1    
172.28.186.1    
172.28.187.1    
172.27.188.1    
172.28.189.1    
172.28.190.1    
172.27.191.1    
172.27.192.1    
172.28.193.1    
172.27.194.1    
172.27.195.1    
172.27.196.1    
172.27.197.1    
172.28.198.1    
172.28.199.1    
10.173.0.1  
10.172.1.1  
10.173.2.1  
10.173.3.1  
10.173.4.1  

解决方案

脚本冻结的核心原因是无限制的后台进程导致资源耗尽,以及SSH/rsync连接未设置足够严格的超时机制,以下是针对性优化方案:

1. 核心优化点

  • 限制并发进程数:避免一次性启动数百个rsync进程,占用过多CPU和网络带宽,同时防止服务器拒绝过多连接。
  • 强化超时控制:给SSH和rsync添加多层超时,彻底杜绝连接挂起导致的脚本冻结。
  • 批量处理单IP任务:将单个IP的三个文件传输打包为一个后台任务,简化进程管理。
  • 日志写入优化:避免多进程同时写入日志导致的内容错乱。

2. 修改后的脚本

#!/bin/bash

SSH_KEY=/root/.ssh/id_rsa
current_date=$(date +%Y-%m-%d)
REPORT_FILE="/home/abdulrahman/scs/reports/file_report_$current_date.txt"
# 创建日志目录(如果不存在)
mkdir -p "$(dirname "$REPORT_FILE")"

# 定义要传输的文件列表(数组形式,便于扩展)
declare -a FILES=(
    "/home/abdulrahman/firefox-redhat-default-prefs.js:/usr/lib64/firefox/browser/defaults/preferences/"
    "/etc/hosts:/etc/"
    "/home/abdulrahman/Tamweely-CA.cer:/"
)

# 并发进程数限制(根据服务器性能调整,建议10-20)
MAX_PARALLEL=15

# 优化ping检测:更快判断主机存活
ping_ip() {
    local ip=$1
    ip=$(echo "$ip" | tr -cd '[:digit:].')
    [ -z "$ip" ] && echo "跳过无效IP" && return 1
    # 使用fping更快(如果没有则用原ping),或者保留ping但缩短超时
    if command -v fping >/dev/null 2>&1; then
        fping -t 2000 -c 1 "$ip" >/dev/null 2>&1
    else
        ping -W 2 -c 1 "$ip" >/dev/null 2>&1
    fi
    if [ $? -eq 0 ]; then
        echo "IP $ip 在线"
        return 0
    else
        echo "IP $ip 离线"
        return 1
    fi
}

# 单个IP的完整文件传输任务
process_ip() {
    local ip_addr=$1
    local success=0
    local fail=0

    # SSH超时配置:连接超时10秒,每5秒发心跳,3次无响应则断开
    SSH_OPTS="-o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ServerAliveInterval=5 -o ServerAliveCountMax=3"
    
    for file_pair in "${FILES[@]}"; do
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:32:50