如何优化bash脚本中用于网络MAC扫描的多条Nmap命令写法?
脚本优化方案
核心优化点
- 砍掉重复的全网段扫描:原脚本每检测到一个陌生MAC,最多会触发3次
nmap -sn全网段扫描,耗时极高。优化后仅在脚本启动时执行1次全网段扫描,后续所有IP、MAC提取都复用该结果 - 移除冗余临时文件:通过管道和命令替换直接提取所需IP值,不需要创建tmpmac.txt、tmpip.txt中间文件
- 修正变量命名:原脚本中存储IP的变量命名为
unknown_mac容易产生歧义,调整为unknown_ip - 合并重复的日志写入、邮件发送逻辑,减少冗余代码
优化后完整代码
#!/bin/bash LOG_FILE="/home/pi/mac_scan.log" ARP_TABLE="/home/pi/arp_table.txt" # 提前执行一次全网段扫描,结果存入变量复用 SCAN_RESULT=$(nmap -sn 192.168.0.0/24) echo "<<---AUTOMATIC SCAN--->>" >> "$LOG_FILE" date >> "$LOG_FILE" # 提取所有MAC地址存入数组 readarray -t mac < <(echo "$SCAN_RESULT" | grep "MAC" | awk '{print $3}' | sort) foundall=true for address in "${mac[@]}"; do if ! grep -Fxq "$address" "$ARP_TABLE"; then echo "WARNING: $address is an unknown device on the network" >> "$LOG_FILE" # 提取陌生设备对应的IP unknown_ip=$(echo "$SCAN_RESULT" | grep -B 2 "$address" | awk '/Nmap scan report/{print $5}') # 发送陌生设备通知邮件 echo "$SCAN_RESULT" | grep -B 2 "$address" | tee -a "$LOG_FILE" | mutt -s "Unknown Devices on Network" XXXXXXX@yahoo.com # 执行OS扫描并发送邮件 echo "MAC SEARCH RESULTS: $address" >> "$LOG_FILE" # 注意nmap -O需要root权限,运行脚本需加sudo nmap -O "$unknown_ip" | tee -a "$LOG_FILE" | mutt -s "OS Scan for $address" XXXXXXXX@yahoo.com foundall=false fi done if [ "$foundall" = true ]; then echo "All Devices are familiar on your network" | tee -a "$LOG_FILE" fi
额外优化建议
- 可以把脚本里的邮箱地址、网段、文件路径都提取成开头的变量,后续修改更方便
- 脚本运行前可以加锁,避免同时运行多个扫描进程冲突
- 如果要长期运行,可以把脚本加入crontab定时执行,注意配置sudo免密运行nmap的权限
内容的提问来源于stack exchange,提问作者spanky
相关产品推荐
相关产品推荐

