Bash脚本仅能扫描首个IP,如何实现遍历IP端口的Nmap批量扫描
修复后的可运行实现
原脚本核心问题定位
- 变量赋值时机错误:
portsvar、hostvar在循环启动前就完成赋值,Shell变量是赋值时刻的内容快照,循环内后续修改临时文件的操作不会同步更新已赋值的变量,导致全程仅使用第一个IP的配置完成扫描 - 输出重复根源:循环内每次执行
cat scanResults时,会把累计到当前时刻的全量结果文件全部打印,匹配5个IP就会把完整的扫描输出重复打印5次 - Nmap参数格式错误:未按Nmap混合协议扫描的要求,给TCP/UDP端口分别加
T:/U:前缀,UDP端口无法被正常识别扫描 - 未实现双写需求:仅靠
>>重定向把内容写入文件,无法同时在终端实时展示扫描进度
完整修复版脚本
#!/bin/bash # 初始化清空旧的扫描结果文件,避免历史内容干扰 > scanResults # 逐行读取IP清单,跳过空行 while read -r target_ip; do # 跳过空行 [[ -z "$target_ip" ]] && continue # 从端口清单中提取当前IP的所有端口,拼接成Nmap合规的端口参数 port_args=$(awk -v current_ip="$target_ip" ' $1 == current_ip { proto = tolower($3) # 按协议追加对应Nmap前缀,UDP端口加U:,默认按TCP处理加T: if (proto == "udp") { printf "U:%s,", $2 } else { printf "T:%s,", $2 } } END { # 去掉拼接串末尾多余的逗号 sub(/,$/, "") } ' portsList) # 未匹配到当前IP的端口条目时跳过扫描 [[ -z "$port_args" ]] && continue # 自动判断是否需要开启UDP扫描 scan_opt="-sS" [[ "$port_args" == *"U:"* ]] && scan_opt="-sS -sU" # 执行扫描:结果实时输出到终端,同时追加存入结果文件 echo "===== 目标 $target_ip 扫描启动,端口集:$port_args =====" | tee -a scanResults nmap -n $scan_opt -sV -p"$port_args" "$target_ip" | tee -a scanResults done < ipList
关键逻辑说明
- 每个IP仅在循环中被处理一次,无重复扫描、重复打印全量输出的问题
- 自动识别端口协议,正确生成Nmap可识别的混合协议扫描参数,比如TCP80、UDP53会自动拼接为
T:80,U:53的格式 - 自动检测端口集是否包含UDP条目,按需为Nmap追加
-sU扫描参数,确保UDP端口能被正常探测 - 借助
tee命令实现输出双写,无需额外配置即可同时完成结果存储和终端实时展示 - 去掉冗余的全文件回读逻辑,从根源上消除重复打印的问题
内容的提问来源于stack exchange,提问作者BZHat
相关产品推荐
相关产品推荐

