最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SSH高效實現(xiàn)批量連接服務器的最佳實踐與避坑指南

 更新時間:2026年01月27日 09:07:51   作者:碼農(nóng)阿豪@新空間  
在運維工作中,我們常常需要管理大量服務器,本文詳細記錄了運維工作中批量測試SSH連接的完整解決方案,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下

引言:當自動化遇到現(xiàn)實挑戰(zhàn)

在運維工作中,我們常常需要管理大量服務器。最近我遇到一個實際需求:需要快速測試一批服務器的SSH連接性,所有服務器都使用相同的root賬號和密碼。這聽起來應該很簡單,但實施過程中卻遇到了各種意想不到的問題。本文將詳細記錄這次實戰(zhàn)經(jīng)歷,分享完整的解決方案,并總結(jié)出可靠的最佳實踐。

需求分析:明確目標與約束條件

原始需求

  • 測試一批IP地址的22端口SSH連接
  • 使用固定賬號:root
  • 使用固定密碼:mn150@2099A
  • 需要超時控制(2-3秒)
  • 結(jié)果分類:成功與失敗的IP分別保存
  • 支持批量處理(IP數(shù)量可能達到數(shù)百個)

技術約束

  • 運行環(huán)境:CentOS 7
  • 網(wǎng)絡條件:可能存在網(wǎng)絡延遲和防火墻限制
  • 安全考慮:雖然使用密碼認證,但這是測試環(huán)境

技術選型:多種方案的對比

方案一:sshpass + 循環(huán)(最直接)

sshpass -p '密碼' ssh -o ConnectTimeout=5 root@IP "命令"

優(yōu)點:簡單直接,無需額外依賴

缺點:缺乏并行處理,速度慢

方案二:expect腳本(更健壯)

expect << EOF
spawn ssh root@IP
expect "password:" { send "密碼\r" }
expect eof
EOF

優(yōu)點:處理交互更穩(wěn)定

缺點:語法復雜,調(diào)試困難

方案三:Python + Paramiko(功能強大)

import paramiko
ssh = paramiko.SSHClient()
ssh.connect(hostname=ip, username='root', password='密碼', timeout=3)

優(yōu)點:功能全面,錯誤處理完善

缺點:需要Python環(huán)境

方案四:并行處理(效率最高)

cat iplist.txt | parallel -j 20 "測試命令"

優(yōu)點:大幅提升測試速度

缺點:并發(fā)控制復雜,容易出錯

實戰(zhàn)過程:從簡單到復雜的演進

第一階段:基礎腳本開發(fā)

最初的腳本很簡單:

#!/bin/bash
PASSWORD='mn150@2099A'

while read ip; do
    sshpass -p "$PASSWORD" ssh -o ConnectTimeout=3 root@$ip "echo ok"
    if [ $? -eq 0 ]; then
        echo "$ip" >> success.txt
    else
        echo "$ip" >> fail.txt
    fi
done < iplist.txt

這個腳本能工作,但存在幾個問題:

  • 沒有進度顯示
  • 錯誤處理不完善
  • 串行執(zhí)行,速度慢

第二階段:添加功能增強

改進版本增加了以下功能:

#!/bin/bash
# 配置參數(shù)
PASSWORD='mn150@2099A'
TIMEOUT=3
IP_FILE="iplist.txt"
SUCCESS_FILE="success_ips.txt"
FAILED_FILE="failed_ips.txt"

# 統(tǒng)計和進度
TOTAL=$(wc -l < "$IP_FILE")
COUNT=0

echo "開始測試 $TOTAL 個IP..."

while read ip; do
    COUNT=$((COUNT + 1))
    echo -n "[$COUNT/$TOTAL] 測試 $ip ... "
    
    timeout $TIMEOUT sshpass -p "$PASSWORD" ssh \
        -o ConnectTimeout=$TIMEOUT \
        -o StrictHostKeyChecking=no \
        root@"$ip" "exit" 2>/dev/null
    
    if [ $? -eq 0 ]; then
        echo "成功"
        echo "$ip" >> "$SUCCESS_FILE"
    else
        echo "失敗"
        echo "$ip" >> "$FAILED_FILE"
    fi
done < "$IP_FILE"

這個版本已經(jīng)有了基本框架,但仍然不夠理想。

第三階段:遇到的坑與解決方案

坑1:腳本編碼問題

現(xiàn)象:腳本只運行了4個IP就停止

錯誤信息./ssh_batch_test.sh: line 1: i#!/bin/bash: No such file or directory

根本原因:腳本文件編碼問題,可能是從Windows復制過來,或者編輯器保存時加入了BOM頭。

解決方案

# 檢查文件編碼
file ssh_batch_test.sh

# 修復編碼問題
sed -i '1s/^.*#!/#!/' ssh_batch_test.sh
# 或者重新創(chuàng)建腳本
cat > new_script.sh << 'EOF'
#!/bin/bash
# 正確內(nèi)容
EOF

坑2:IP文件格式問題

現(xiàn)象:雖然IP文件有200多個IP,但腳本只處理了4個

可能原因

  • Windows換行符(CRLF)
  • 文件中有特殊字符
  • 讀取邏輯有缺陷

解決方案

# 檢查文件格式
cat -A iplist.txt | head -10

# 修復換行符
dos2unix iplist.txt
# 或者使用sed
sed -i 's/\r$//' iplist.txt

# 清理文件
grep -v '^[[:space:]]*$' iplist.txt | grep -v '^#' > iplist_clean.txt

坑3:SSH選項沖突

現(xiàn)象:手動測試成功,但腳本測試失敗

關鍵發(fā)現(xiàn)-o BatchMode=yes選項會禁用密碼認證!

錯誤配置

# 這個會失敗
sshpass -p '密碼' ssh -o BatchMode=yes root@IP "命令"

# 正確的應該是
sshpass -p '密碼' ssh -o BatchMode=no root@IP "命令"
# 或者干脆不要BatchMode選項

坑4:并發(fā)寫入沖突

現(xiàn)象:并行腳本運行異常,結(jié)果不完整

原因:多個進程同時寫入同一個文件

解決方案

# 每個進程寫入獨立文件,最后合并
TEMP_DIR=$(mktemp -d)
# 每個進程寫入 $TEMP_DIR/result_$PID
# 最后 cat $TEMP_DIR/* > final_result.txt

第四階段:最終穩(wěn)定版本

經(jīng)過多次調(diào)試,最終得到了穩(wěn)定可靠的版本:

#!/bin/bash
# SSH批量測試腳本 - 最終穩(wěn)定版

set -u  # 使用未定義變量時報錯
set -e  # 遇到錯誤時退出

# 配置參數(shù)
PASSWORD='mn150@2099A'
CONNECT_TIMEOUT=3
IP_FILE="${1:-iplist.txt}"

# 生成帶時間戳的結(jié)果文件
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
SUCCESS_FILE="success_ips_${TIMESTAMP}.txt"
FAILED_FILE="failed_ips_${TIMESTAMP}.txt"

# 驗證環(huán)境
validate_environment() {
    # 檢查sshpass
    if ! command -v sshpass &> /dev/null; then
        echo "錯誤: sshpass 未安裝"
        echo "請執(zhí)行: sudo yum install -y epel-release sshpass"
        exit 1
    fi
    
    # 檢查IP文件
    if [ ! -f "$IP_FILE" ]; then
        echo "錯誤: IP文件 $IP_FILE 不存在"
        exit 1
    fi
    
    # 檢查文件是否可讀
    if [ ! -r "$IP_FILE" ]; then
        echo "錯誤: 無法讀取IP文件 $IP_FILE"
        exit 1
    fi
}

# 清理和驗證IP列表
prepare_ip_list() {
    local input_file="$1"
    local output_file="$2"
    
    # 清空輸出文件
    > "$output_file"
    
    # 處理IP文件:移除注釋、空行、換行符
    while IFS= read -r line || [ -n "$line" ]; do
        # 移除換行符和回車符
        line=$(echo "$line" | tr -d '\r')
        
        # 跳過空行和注釋
        if [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]]; then
            continue
        fi
        
        # 提取IP(移除可能的后綴和注釋)
        ip=$(echo "$line" | sed 's/[[:space:]].*$//' | sed 's/#.*$//')
        
        # 驗證IP格式
        if [[ "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            echo "$ip" >> "$output_file"
        else
            echo "警告: 跳過無效IP格式: $ip" >&2
        fi
    done < "$input_file"
}

# 測試單個IP
test_single_ip() {
    local ip="$1"
    
    # 使用timeout防止命令掛起
    timeout ${CONNECT_TIMEOUT} sshpass -p "$PASSWORD" ssh \
        -o ConnectTimeout=${CONNECT_TIMEOUT} \
        -o StrictHostKeyChecking=no \
        -o PasswordAuthentication=yes \
        -o BatchMode=no \
        -o LogLevel=ERROR \
        root@"$ip" "exit 0" 2>/dev/null
    
    return $?
}

# 主函數(shù)
main() {
    echo "========================================"
    echo "SSH批量連接測試工具"
    echo "========================================"
    echo "賬號:        root"
    echo "超時時間:    ${CONNECT_TIMEOUT}秒"
    echo "IP文件:      $IP_FILE"
    echo "結(jié)果文件:"
    echo "  成功IP:    $SUCCESS_FILE"
    echo "  失敗IP:    $FAILED_FILE"
    echo "========================================"
    
    # 驗證環(huán)境
    validate_environment
    
    # 準備IP列表
    local clean_ip_file="/tmp/clean_ips_$$.txt"
    prepare_ip_list "$IP_FILE" "$clean_ip_file"
    
    local total_ips=$(wc -l < "$clean_ip_file" 2>/dev/null || echo 0)
    if [ $total_ips -eq 0 ]; then
        echo "錯誤: 沒有有效的IP地址可以測試"
        exit 1
    fi
    
    echo "找到 $total_ips 個有效IP地址"
    echo ""
    
    # 清空結(jié)果文件
    > "$SUCCESS_FILE"
    > "$FAILED_FILE"
    
    # 開始測試
    echo "開始測試..."
    echo "----------------------------------------"
    
    local tested=0
    local success=0
    local failed=0
    
    while read ip; do
        tested=$((tested + 1))
        
        # 顯示進度(每10個IP顯示一次)
        if [ $((tested % 10)) -eq 0 ] || [ $tested -eq $total_ips ]; then
            printf "\r進度: %d/%d (%.1f%%)" $tested $total_ips $(echo "scale=1; $tested*100/$total_ips" | bc)
        fi
        
        # 測試連接
        if test_single_ip "$ip"; then
            echo "$ip" >> "$SUCCESS_FILE"
            success=$((success + 1))
        else
            echo "$ip" >> "$FAILED_FILE"
            failed=$((failed + 1))
        fi
    done < "$clean_ip_file"
    
    echo ""
    echo "----------------------------------------"
    echo ""
    
    # 生成報告
    echo "測試完成!"
    echo "========================================"
    echo "統(tǒng)計結(jié)果:"
    echo "  總IP數(shù):    $total_ips"
    echo "  成功數(shù):    $success"
    echo "  失敗數(shù):    $failed"
    
    if [ $total_ips -gt 0 ]; then
        local success_rate=$(echo "scale=2; $success * 100 / $total_ips" | bc)
        echo "  成功率:    ${success_rate}%"
    fi
    
    echo ""
    echo "結(jié)果文件已生成:"
    echo "  $SUCCESS_FILE"
    echo "  $FAILED_FILE"
    
    # 顯示示例結(jié)果
    if [ -s "$SUCCESS_FILE" ]; then
        echo ""
        echo "成功IP示例(前5個):"
        head -5 "$SUCCESS_FILE" | cat -n
    fi
    
    # 清理臨時文件
    rm -f "$clean_ip_file"
}

# 執(zhí)行主函數(shù)
main

關鍵技術與最佳實踐

1. 健壯的IP文件處理

# 正確處理各種格式的IP文件
while IFS= read -r line || [ -n "$line" ]; do
    # 處理換行符
    line=$(echo "$line" | tr -d '\r')
    
    # 驗證IP格式
    if [[ "$line" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
        # 有效IP
    fi
done < ipfile.txt

2. 適當?shù)腟SH選項配置

# 推薦的SSH選項組合
sshpass -p "$PASSWORD" ssh \
    -o ConnectTimeout=$TIMEOUT \      # 連接超時
    -o StrictHostKeyChecking=no \     # 不檢查主機密鑰(測試環(huán)境)
    -o PasswordAuthentication=yes \   # 允許密碼認證
    -o BatchMode=no \                 # 不禁用密碼認證!
    -o LogLevel=ERROR \               # 只顯示錯誤日志
    root@"$IP" "命令"

3. 合理的錯誤處理

# 使用timeout防止命令掛起
timeout $TIMEOUT 命令

# 檢查退出碼
if [ $? -eq 0 ]; then
    # 成功
elif [ $? -eq 124 ]; then
    # 超時
elif [ $? -eq 5 ]; then
    # 認證失敗
else
    # 其他錯誤
fi

4. 進度反饋機制

# 顯示進度百分比
printf "\r進度: %d/%d (%.1f%%)" $current $total $(echo "scale=1; $current*100/$total" | bc)

# 或使用進度條
draw_progress_bar() {
    local current=$1
    local total=$2
    local width=50
    local percent=$((current * 100 / total))
    local completed=$((current * width / total))
    
    printf "\r["
    printf "%${completed}s" | tr ' ' '='
    printf "%$((width - completed))s" | tr ' ' '.'
    printf "] %3d%%" $percent
}

性能優(yōu)化技巧

并行處理方案

對于大量IP的測試,順序執(zhí)行太慢。以下是安全的并行方案:

#!/bin/bash
# 安全的并行測試

PASSWORD='mn150@2099A'
TIMEOUT=3
MAX_JOBS=10

# 創(chuàng)建臨時目錄存放結(jié)果
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT

# 測試函數(shù)
test_ip() {
    local ip=$1
    local pid=$$
    
    timeout $TIMEOUT sshpass -p "$PASSWORD" ssh \
        -o ConnectTimeout=$TIMEOUT \
        -o StrictHostKeyChecking=no \
        root@"$ip" "exit" 2>/dev/null
    
    if [ $? -eq 0 ]; then
        echo "$ip" >> "$TEMP_DIR/success_$pid"
    else
        echo "$ip" >> "$TEMP_DIR/failed_$pid"
    fi
}

# 導出函數(shù)
export -f test_ip
export PASSWORD TIMEOUT TEMP_DIR

# 并行執(zhí)行
cat iplist.txt | xargs -P $MAX_JOBS -I {} bash -c 'test_ip "$@"' _ {}

# 合并結(jié)果
cat "$TEMP_DIR"/success_* 2>/dev/null | sort -u > success.txt
cat "$TEMP_DIR"/failed_* 2>/dev/null | sort -u > failed.txt

資源限制

# 避免過多的并發(fā)連接
ulimit -n 4096  # 增加文件描述符限制

# 限制每個進程的資源使用
prlimit --nproc=100 --nofile=100 --cpu=10 sshpass ...

安全注意事項

盡管這是測試腳本,但仍需注意安全:

  • 密碼處理:不要在腳本中硬編碼密碼,考慮使用環(huán)境變量或配置文件
  • 結(jié)果保護:測試結(jié)果可能包含敏感信息,妥善保管
  • 權限控制:腳本應運行在受控環(huán)境中
  • 日志清理:定期清理日志文件
# 更安全的方式:從環(huán)境變量讀取密碼
PASSWORD=${SSH_PASSWORD:-'default_password'}

# 或者從加密文件讀取
if [ -f ~/.ssh_test_pass ]; then
    PASSWORD=$(openssl enc -d -aes-256-cbc -in ~/.ssh_test_pass)
fi

擴展功能

1. 添加重試機制

test_with_retry() {
    local ip=$1
    local max_retries=2
    
    for ((i=1; i<=max_retries; i++)); do
        if test_single_ip "$ip"; then
            return 0
        fi
        sleep 1
    done
    return 1
}

2. 收集系統(tǒng)信息

# 測試時順便收集信息
collect_info() {
    local ip=$1
    sshpass -p "$PASSWORD" ssh root@"$ip" "
        echo '=== 系統(tǒng)信息 ==='
        uname -a
        echo ''
        echo '=== 內(nèi)存信息 ==='
        free -h
        echo ''
        echo '=== 磁盤信息 ==='
        df -h
    " > "info_${ip}.txt" 2>/dev/null
}

3. 生成HTML報告

generate_html_report() {
    cat > report.html << EOF
<html>
<head>
    <title>SSH測試報告</title>
    <style>
        table { border-collapse: collapse; width: 100%; }
        th, td { border: 1px solid #ddd; padding: 8px; }
        th { background-color: #f2f2f2; }
        .success { background-color: #dff0d8; }
        .failed { background-color: #f2dede; }
    </style>
</head>
<body>
    <h1>SSH連接測試報告</h1>
    <p>生成時間: $(date)</p>
    <p>總計: $total_ips 個IP</p>
    <p>成功: $success 個</p>
    <p>失敗: $failed 個</p>
    
    <h2>成功IP列表</h2>
    <table>
        <tr><th>序號</th><th>IP地址</th></tr>
        $(cat success.txt | awk '{print "<tr class=\"success\"><td>"NR"</td><td>"$1"</td></tr>"}')
    </table>
</body>
</html>
EOF
}

總結(jié)與建議

經(jīng)過這次實戰(zhàn),我總結(jié)了以下經(jīng)驗:

核心原則

  • 簡單可靠勝過復雜先進:先確?;A功能穩(wěn)定
  • 逐步增強:從簡單版本開始,逐步添加功能
  • 充分測試:小范圍測試驗證后再批量運行
  • 錯誤處理:預見到可能的問題并提前處理

技術建議

  • 使用set -euo pipefail讓腳本更健壯
  • 總是驗證輸入數(shù)據(jù)的有效性
  • 為長時間運行的任務添加進度反饋
  • 使用臨時文件處理并發(fā)寫入問題
  • 清理臨時文件和資源

運維建議

  • 保持腳本的日志記錄能力
  • 考慮添加監(jiān)控和告警機制
  • 定期回顧和優(yōu)化腳本
  • 文檔化腳本的使用和維護方法

批量測試SSH連接雖然看起來簡單,但實際實施時會遇到各種預料之外的問題。通過系統(tǒng)的分析和逐步的改進,我們最終得到了一個穩(wěn)定、高效、功能完善的解決方案。這個過程不僅解決了眼前的問題,也為類似任務積累了寶貴經(jīng)驗。

記?。汉玫淖詣踊_本不是一蹴而就的,而是在不斷遇到問題、解決問題的過程中逐漸完善起來的。每個錯誤和調(diào)試過程都是學習和提高的機會。

到此這篇關于SSH高效實現(xiàn)批量連接服務器的最佳實踐與避坑指南的文章就介紹到這了,更多相關SSH批量連接服務器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Git 常用命令速查表(圖文+表格)

    Git 常用命令速查表(圖文+表格)

    這篇文章主要介紹了Git 常用命令速查表(圖文+表格),需要的朋友可以參考下
    2014-09-09
  • 使用GIT進行源碼管理——GUI客戶端小結(jié)

    使用GIT進行源碼管理——GUI客戶端小結(jié)

    很多人對GIT GUI客戶端是非常不屑一顧的,但我非常喜歡GUI的方便快捷,也不用記憶冗雜的命令,本文簡單的介紹了幾種免費的Windows下的GIT客戶端,方便大家使用
    2014-09-09
  • IBM服務器診斷面板使用方法

    IBM服務器診斷面板使用方法

    IBM服務器一般會有一個服務器操作員信息面板(診斷面板),服務器一般的硬件故障都會在診斷面板上提示,但這些提示可能只是一個大概的診斷故障,有助于系統(tǒng)管理員更好的維護
    2018-05-05
  • WordPress網(wǎng)站遷移到新主機防火墻配置

    WordPress網(wǎng)站遷移到新主機防火墻配置

    這篇文章主要為大家介紹了WordPress網(wǎng)站遷移到新主機防火墻配置,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-03-03
  • 通過cmd?連接阿里云服務器的操作方法

    通過cmd?連接阿里云服務器的操作方法

    這篇文章主要介紹了通過cmd連接阿里云服務器,在這里講一下買完服務器的要做的第一步就是去服務器的后臺做相應的操作,本文通過兩種方法給大家講解連接服務器,需要的朋友可以參考下
    2022-04-04
  • git分支管理_動力節(jié)點Java學院整理

    git分支管理_動力節(jié)點Java學院整理

    這篇文章主要為大家詳細介紹了git分支管理的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 樹莓派 msmtp和mutt 的安裝和配置教程

    樹莓派 msmtp和mutt 的安裝和配置教程

    這篇文章主要介紹了樹莓派 msmtp和mutt 的安裝和配置教程,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-07-07
  • git修改和刪除功能_動力節(jié)點Java學院整理

    git修改和刪除功能_動力節(jié)點Java學院整理

    這篇文章主要介紹了git修改和刪除功能,需要的朋友可以參考下
    2017-08-08
  • 自己搭建CDN服務器的工具GoEdge安裝和配置教程

    自己搭建CDN服務器的工具GoEdge安裝和配置教程

    GoEdge是一款基于Go語言開發(fā)的管理分布式CDN邊緣節(jié)點的開源工具軟件,支持多種協(xié)議和功能,包括?HTTP、HTTPS、WebSocket、TCP、TLS、UDP?等,并集成了?WAF(Web?應用防火墻)能力,可以讓用戶輕松地、低成本地創(chuàng)建CDN/WAF等應用
    2025-08-08
  • Apache?Hudi靈活的Payload機制硬核解析

    Apache?Hudi靈活的Payload機制硬核解析

    這篇文章主要為大家介紹了Apache?Hudi靈活的Payload機制超硬核解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-03-03

最新評論

华池县| 土默特右旗| 揭阳市| 运城市| 安徽省| 和政县| 苏尼特左旗| 临沂市| 雷州市| 望奎县| 丰顺县| 汉中市| 疏勒县| 比如县| 斗六市| 宣化县| 泾源县| 宜兰县| 阿拉善左旗| 普兰店市| 青州市| 乐至县| 寿光市| 辽阳县| 和平区| 凤山县| 新昌县| 聊城市| 盱眙县| 大港区| 惠州市| 长海县| 府谷县| 鹿邑县| 牡丹江市| 建水县| 普陀区| 白玉县| 集安市| 广东省| 隆回县|