shell数组本身不支持并发,而是用数组管理主机列表,结合子进程并行、wait限流(50–100)、临时文件收集结果、超时重试及分组探测实现高效批量监控。

在单机 Linux 环境下用 Shell 数组实现“并发监控上千台主机”需明确一点:Shell 本身不支持真正的高并发(如线程/协程),但可通过 子进程并行 + 数组管理主机列表 + 限流控制 实现高效批量探测。关键不是“数组并发”,而是用数组组织目标,再结合 wait、jobs 和合理并发数(如 50–100)避免系统过载。
用数组存储主机列表,支持动态加载和分片
Shell 数组适合存 IP 或域名,尤其配合文件读取或命令生成:
- 从文件初始化:
mapfile -t hosts (每行一个主机,自动去换行符) - 手动定义:
hosts=("192.168.1.1" "10.0.0.5" "example.com") - 支持带端口或协议前缀(如
"ssh://192.168.1.10:22"),后续脚本可解析 - 避免直接写死上千项——用数组变量承接,便于切片处理(如
"${hosts[@]:0:100}"取前 100 台)
用子进程 + wait 控制并发数,避免 fork 爆炸
真正实现“并发”的是后台作业(&),数组只负责调度。例如设最大并发 64:
- 遍历数组,每启动一个
ping -c1 -W2 $host > /dev/null &就计数 - 当后台任务数 ≥ 64 时,执行
wait -n(等待任一子进程退出)再启下一个 - 用
jobs -r | wc -l或更可靠方式(如计数器+trap)跟踪运行中任务数 - 示例核心逻辑:
for host in "${hosts[@]}"; do ((cnt++ % 64 == 0)) && wait -n; ping -c1 -W2 "$host" &>/dev/null & done; wait
用临时文件或管道收集结果,避免 stdout 混乱
上千个并发 ping 直接输出会交错,推荐结构化记录:
- 每个子进程单独写结果到唯一临时文件:
echo "$host:$(ping -c1 -W2 "$host" &>/dev/null && echo up || echo down)" > "/tmp/res.$$.${i}" - 或用命名管道(FIFO)+ 单独 reader 进程汇总,更健壮但稍复杂
- 最终合并:
cat /tmp/res.$$.* 2>/dev/null | sort,再用awk统计存活率 - 注意清理:
trap 'rm -f /tmp/res.$$.*' EXIT
增强实用性:超时、重试、多探测方式混合
仅靠 ping 不足,实际中常组合判断:
- 对无 ICMP 响应的主机,补充 telnet 或 curl 检查关键端口:
timeout 3 bash -c 'echo > /dev/tcp/$host/22' &>/dev/null && echo "$host ssh ok" - 失败后自动重试一次(加
||链式调用),避免瞬时丢包误判 - 将主机按类型分组存不同数组(如
web_hosts、db_hosts),分别设置探测策略 - 结果输出为 CSV 或 JSON 格式,方便下游处理:
printf '%s,%s\n' "$host" "$status" >> report.csv
不复杂但容易忽略:Shell 并发本质是进程级并行,受限于系统 ulimit -u(用户进程数)和内存。实测千台主机建议并发 50–80,全程耗时约 2–5 秒(取决于网络延迟),比串行快 50 倍以上。数组在这里是轻量、灵活的索引工具,而非并发引擎本身。











