如何在bash两层循环中遍历数组并过滤Nmap扫描的指定IP
问题根因
- 核心错误在IP匹配逻辑:原有判断语句
if [ $host == $check."${ignore[@]}" ]会将整个ignore数组的所有元素拼接为单个字符串,无法逐个匹配IP末尾八位组 - Nmap输出处理的sed语句存在语法错误:
sed -e "$d"中的$未转义,会被shell识别为变量而非sed的「删除最后一行」指令 - 不需要额外校验IP前三段,当前循环已经对应同一个vlan子网,只需要校验最后一个八位组即可
修复后完整脚本
#!/bin/bash declare -a vlans=( 10.6.114 10.6.115 10.5.120 ) declare -a ignore=( 1 2 3 252 253 254 ) for vlan in "${vlans[@]}"; do # 扫描子网并提取存活IP,修复sed语法错误,减少冗余管道 nmap -sn "$vlan.0/24" | awk '/Nmap scan report for/ {print $5}' | sed '$d' | sort > /tmp/vlan_ips.txt readarray -t hosts < /tmp/vlan_ips.txt for host in "${hosts[@]}"; do # 用shell参数扩展提取最后一位八位组,无需调用cut,效率更高 last_octet=${host##*.} # 判断当前尾段是否在忽略列表中 if [[ " ${ignore[*]} " =~ " ${last_octet} " ]]; then echo "skipping record: $host" # 跳过后续逻辑,直接处理下一个IP continue fi # 这里写你需要对非忽略IP执行的后续逻辑 echo "processing valid IP: $host" done done
核心修改说明
- 给nmap的扫描目标补全了
/24掩码,明确扫描C类子网的所有IP,避免nmap默认只扫描单个IP的问题 - 替换cut命令为shell原生参数扩展
${host##*.}提取IP最后一段,减少子进程开销 - 采用
[[ " ${ignore[*]} " =~ " ${last_octet} " ]]实现忽略列表匹配,逻辑简单高效 - 增加
continue语句,匹配到忽略IP后直接跳过后续处理逻辑
内容的提问来源于stack exchange,提问作者hagay_bar
相关产品推荐
相关产品推荐

