bash - 如何在 bash 脚本中使这些多个 Nmap 命令更优雅?
问题描述
我有一个我一直在处理的小型项目脚本,它会扫描我的网络以查找新的 MAC 地址,并在我的网络上是否有不熟悉的设备时通知我。
我已经介绍了在未知 MAC 地址(如果有)上自动执行操作系统扫描的功能。但是,我只能通过将 ping 扫描的 grepped 部分保存到一个临时文件 (tmpmac.txt) 中,然后将该文件中的 IP 地址 grep 到一个额外的临时文件 (tmpip.txt) 中来实现这一点,如-O Nmap 选项需要 IP 才能扫描:
nmap -sn 192.168.0.0/24 | grep -B 2 "$address" > /home/pi/tmpmac.txt
cat /home/pi/tmpmac.txt | grep "Nmap" | awk {'print $5'} > /home/pi/tmpip.txt
unknown_mac=$( cat /home/pi/tmpip.txt )
nmap -O $unknown_mac | tee -a /home/pi/mac_scan.log | mutt -s "OS Scan for $address" XXXXXXXX@gmail.com
整个脚本:
echo "<<---AUTOMATIC SCAN--->>" >>/home/pi/mac_scan.log
date >>/home/pi/mac_scan.log
nmap -sn 192.168.0.0/24 | grep "MAC" | awk '{print $3}'| sort > /home/pi/arp.txt
readarray -t mac </home/pi/arp.txt
foundall=true
for address in "${mac[@]}"; do
if ! grep -Fxq "$address" /home/pi/arp_table.txt;
then
echo "WARNING: $address is an unknown device on the network" >> /home/pi/mac_scan.log
nmap -sn 192.168.0.0/24 | grep -B 2 "$address" | tee -a /home/pi/mac_scan.log | mutt -s "Unknown Devices on Network" XXXXXXX@yahoo.com
echo ""
echo "MAC SEARCH RESULTS: $address" >> /home/pi/mac_scan.log
nmap -sn 192.168.0.0/24 | grep -B 2 "$address" > /home/pi/tmpmac.txt
cat /home/pi/tmpmac.txt | grep "Nmap" | awk {'print $5'} > /home/pi/tmpip.txt
unknown_mac=$( cat /home/pi/tmpip.txt )
nmap -O $unknown_mac | tee -a /home/pi/mac_scan.log | mutt -s "OS Scan for $address" XXXXXXXX@yahoo.com
foundall=false
fi
done
[[ "${foundall}" == 'true' ]] && echo "All Devices are familiar on your network" | tee -a /home/pi/mac_scan.log
当前形式的脚本执行其应有的方式,但我很好奇是否有更优雅的方式来实现这一点。
解决方案
我nmap
的输出显然与你的不同,所以我无法对此进行测试,但我看不出有任何理由不跳过所有文件,并将整个管道放在一个var=$(command)
结构中:
unknown_mac=$( nmap -sn 192.168.0.0/24 |
grep -B 2 "$address" |
grep "Nmap" |
awk {'print $5'} )
但是,整个脚本会运行nmap -sn 192.168.0.0/24
多次(开始时运行一次,然后每个新主机运行两次);为什么不一开始就将它存储在一个变量(或者可能是文件)中,然后在需要时使用它呢?
hostscan=$(nmap -sn 192.168.0.0/24)
...
echo "$hostscan" | othercommand
# or:
othercommand <<<"$hostscan"
# or if you prefer:
<<<"$hostscan" othercommand
请注意,在使用变量时双引号很重要。实际上,您几乎应该总是用双引号引用变量引用;有时您可以跳过双引号而侥幸,但了解何时安全比它的价值更麻烦。脚本中还有很多其他地方应该执行此操作。shellcheck.net擅长指出它们以及其他常见错误;我建议通过它运行您的脚本并修复它指出的内容。
你也可以折叠grep "somestring" | awk '{print $1}'
到 just awk '/somestring/ {print $1}
。通过所有这些更改,捕获未知 MAC 只是:
unknown_mac=$(<<<"$hostscan" grep -B 2 "$address" | awk '{/Nmap/ print $5}')
您还可以使用 here-string ( <<<
) with readarray
(注意:放在readarray
管道的末尾是行不通的,因为管道中的东西在子外壳中运行):
readarray -t mac <<<"$(<<<"$hostscan" awk '/MAC/ {print $3}' | sort)"
推荐阅读
- javascript - 如何在柏树中编写编辑图标的点击功能
- oracle - 防止 oracle 数据库计划作业在计划时间后运行
- r - 在我的数据集中添加分组变量的更好方法
- vim - 是否可以删除除所选文本之外的所有内容?
- java - 使用单车或工具 CVRP 重新加载
- rest - OpenAPI 3.0 规范中哪里允许使用 $ref?
- c# - 有没有办法让布局元素自动重新缩放而不是自动调整大小?
- apollo - 在生产模式下是否有任何选项可以禁用游乐场?
- jquery - UI 不显示列的标签(数据类型:文本)
- python - 为什么整数的 Python sum() 和 np.sum() 不同?