如何改造Bash批量Ping脚本实现并行执行以提速?
把批量Ping脚本改成并行执行的方案
嘿,我来帮你改造这个脚本,让它能并行处理所有主机,大幅提升运行速度!核心思路是把每个主机的Ping任务放到后台独立执行,最后等待所有任务完成。下面是具体的修改方案:
修改后的完整脚本
#!/bin/bash # 并行批量Ping脚本,输出CSV格式结果 # 定义处理单个主机的函数 ping_host() { local output="$1" # 先快速检测主机是否可达 if ping -c 1 -w 1 "$output" > /dev/null; then # 可达的话,Ping4次取平均延迟 pingtime=$(ping -c 4 "$output" | tail -1 | awk -F '/' '{print $5}') echo "$(date '+%Y-%m-%d %H:%M:%S,%3N');$output;UP;$pingtime" else # 不可达的输出 echo "$(date '+%Y-%m-%d %H:%M:%S,%3N');$output;Down;Unknown" fi } Inputlist=./1A/list.txt # 循环读取每个主机,后台执行ping_host函数 while read -r output; do ping_host "$output" & done < "$Inputlist" # 等待所有后台Ping任务完成 wait
关键修改点解释
- 封装处理逻辑为函数:把原来循环里的Ping检测逻辑放到
ping_host函数里,用local声明变量,避免后台进程之间的变量冲突,同时让代码更清晰易维护。 - 后台执行任务:在调用
ping_host时加上&,这会让每个Ping任务在后台独立运行,脚本不用等当前任务完成就会处理下一个主机,实现并行效果。 - 等待所有任务结束:循环结束后加上
wait命令,它会让脚本一直等到所有后台进程都执行完毕再退出,避免脚本提前结束导致部分Ping任务没完成。
可选优化:控制并发数
如果你的主机列表特别长(比如几百上千个),一下子启动所有后台进程可能会占用过多系统资源。可以加个并发数控制,比如每次最多同时跑10个任务:
#!/bin/bash # 带并发数控制的并行批量Ping脚本 ping_host() { local output="$1" if ping -c 1 -w 1 "$output" > /dev/null; then pingtime=$(ping -c 4 "$output" | tail -1 | awk -F '/' '{print $5}') echo "$(date '+%Y-%m-%d %H:%M:%S,%3N');$output;UP;$pingtime" else echo "$(date '+%Y-%m-%d %H:%M:%S,%3N');$output;Down;Unknown" fi } Inputlist=./1A/list.txt MAX_CONCURRENT=10 count=0 while read -r output; do ping_host "$output" & ((count++)) # 当达到最大并发数时,等待一批任务完成 if ((count % MAX_CONCURRENT == 0)); then wait count=0 fi done < "$Inputlist" # 等待最后一批剩余的任务完成 wait
这个版本会每启动10个任务就暂停一下,等这10个都跑完再继续下一批,避免系统负载过高。
注意事项
- 并行执行后,输出的顺序可能会和输入列表的顺序不一致(因为不同主机的Ping耗时不同),如果需要严格按输入顺序输出,你可以让每个任务把结果写到单独的临时文件,最后按输入顺序合并,但这会增加一点复杂度。
- 确保你的系统允许同时创建足够多的进程,一般来说几十上百个都没问题,但如果是几千个主机,还是建议用并发数控制。
内容的提问来源于stack exchange,提问作者Eideen
相关产品推荐
相关产品推荐

