如何实现基于IP列表的Shell+expect脚本并行执行提速
JUNOS版本批量检查脚本并行改造方案
原有串行脚本逐台等待SSH交互完成,执行效率随IP列表长度线性下降,采用可控并发数的后台异步执行+临时结果汇总方案即可实现并行加速,无需安装额外依赖,原生Bash即可支持。
改造注意事项
- 不可无限制启动后台进程,否则会耗尽本地文件描述符,还可能触发网络设备侧的SSH连接数限制,建议初始并发值设置为10~20,可根据实际环境调整
- 多进程不可直接写入同一个结果文件,否则会出现行内容穿插、乱序问题,需先将单台设备结果写入独立临时文件,所有任务完成后统一汇总
- 保留原有所有SSH加密算法兼容参数、版本过滤规则,保证和原脚本输出格式完全一致
改造后完整脚本
#!/bin/bash HOST_LIST="$1" USER="user" PASS="password" OUT="checkversion.csv" # 并发数,可根据实际环境调整 PARALLEL=15 # 初始化结果文件 rm -rf $OUT touch $OUT # 创建临时目录存储单台设备的执行结果 TMP_DIR=$(mktemp -d) NOW=$(date +"%Y-%m-%d_%H-%M-%S") echo "Script started at $NOW" # 定义单台设备的检查逻辑 check_version() { local ip=$1 local tmp_file=$2/$ip.result SCRIPT=$(expect -c " spawn ssh -o HostKeyAlgorithms=+ssh-dss -o KexAlgorithms=+diffie-hellman-group1-sha1 -o StrictHostKeyChecking=no -c 3des-cbc -c aes128-cbc -c aes192-cbc -c aes256-cbc -c aes128-ctr -c aes192-ctr -c aes256-ctr $USER@$ip match_max 100000 expect \"*?assword:*\" send -- \"$PASS\r\" expect \"*>*\" send -- \"start shell\" send -- \"\r\" expect \"*%*\" send -- \"exit\" send -- \"\r\" expect \"*>*\" send -- \"exit\" send -- \"\r\" ") VERSION=$(echo "$SCRIPT" | grep JUNOS | grep -v WARNING | grep -v possible | grep -v recover) echo "$ip;$VERSION" > $tmp_file } # 遍历IP列表启动并行任务 for ip in $(cat $HOST_LIST) do # 后台启动单台检查任务 check_version $ip $TMP_DIR & # 当后台任务数达到并发上限时,等待当前批次任务执行完成 if [ $(jobs -p | wc -l) -ge $PARALLEL ]; then wait fi done # 等待最后一批任务全部执行完成 wait # 汇总所有临时结果到最终csv文件 cat $TMP_DIR/*.result >> $OUT # 清理临时目录 rm -rf $TMP_DIR NOW=$(date +"%Y-%m-%d_%H-%M-%S") echo "script finished at $NOW - note any errors above"
使用说明
- 脚本使用方式和原版本完全一致,执行
./脚本名 IP列表文件路径即可 - 若出现部分设备连接超时、登录失败的情况,可适当调低
PARALLEL参数值 - 最终输出的
checkversion.csv格式和原脚本完全一致,无需调整后续解析逻辑
内容的提问来源于stack exchange,提问作者Andrea Del Gaudio
相关产品推荐
相关产品推荐

