尝试获取 BASH 备份脚本以根据已知 MAC 地址查找 IP 地址?

Trying to get BASH backup script to find an IP address based off known MAC address?

我有一个小的 BASH 备份脚本,它使用 Rsync 在我的 LAN 上抓取一些计算机。它适用于使用以太网电缆的静态设备 - 问题出现在我拥有扩展坞的笔记本电脑用户中。每隔一段时间,他们就不会连接到 Dock & Ethernet cable/statically 分配的地址,最终会使用 DHCP 分配的地址连接到 WiFi。我已经在一个文件中有一个已知的静态分配目标列表,该文件被解析到实际备份。所以我一直在想,我应该能够很容易地在每次备份之前使用 nmap 扫描创建第二个文件 运行 以及我发现的其他代码 - 例如:

    sudo nmap -n -sP 192.168.2.0/24 | awk '/Nmap scan report for/{printf ;}/MAC Address:/{print " => ";}' | sort

它为我提供了 192.168.2.101 => B4:FB:E4:FE:C6:6F 的列表,用于在 LAN 中找到的所有设备。我刚刚删除了 |排序并将其发送到文件 > found.devices 而不是。

所以现在我有一个找到的设备 IP 和 MAC 地址的列表 - 我想比较这两个文件并创建一个新的目标列表,其中包含找到的任何已更改的 IP 地址(对于那些笔记本电脑用户忘记连接到 Dock,现在正在使用 DHCP)。但我仍然想在他们记得的时候保持我的原始目标文件干净,并继续获取那些一直有线的其他设备,同时忽略 LAN 上的所有其他内容。

found.devices
192.168.2.190 => D4:XB:E4:FE:C6:6F
192.168.2.102 => B4:QB:Y4:FE:C6:6F
192.168.2.200 => B4:FB:P4:ZE:C6:6F
192.168.2.104 => B4:FB:E4:BE:P6:6F

known.targets
192.168.2.101 D4:XB:E4:FE:C6:6F domain source destination 
192.168.2.102 B4:QB:Y4:FE:C6:6F domain source destination 
192.168.2.103 B4:FB:P4:ZE:C6:6F domain source destination 
192.168.2.104 B4:FB:E4:BE:P6:6F domain source destination 

Should get a list or a file for the current back run to use of:
192.168.2.190 domain source destination
192.168.2.102 domain source destination
192.168.2.200 domain source destination
192.168.2.104 domain source destination

目前我的 bash 脚本一次只读取 known.targets 一行的文件:

cat /known.targets | while read ip hostname source destination
     do 
     this mounts and backs up the data I want ... 

我真的很喜欢当前的系统,并且发现它对于我的简单需求非常可靠,只是需要找到一些方法来吸引那些间歇性忘记停靠的用户。我期待它的一系列嵌套循环,但我无法理解它 - 远离实际编码太久 - 任何建议将不胜感激。我也真的很想摆脱 => 并只使用逗号或 space 分隔的数据,但每次我弄乱那个 awk 语句 - 我最终移动数据并在我不能的地方得到一个奇怪的 CR算了吧!

更新: 根据 OP 的评论,放弃关于保持 IP 地址显示在 found.devices 但在 [= 中没有匹配的假设(和相关代码) 16=](即,这不可能发生)


假设:

  • known.targets
  • 中的 IP/MAC 个地址列表开始
  • 如果 MAC 地址也出现在 found.devices 中,则 found.devices 中的 IP 地址优先

向两个文件添加独立条目:

$ cat known.targets
192.168.2.101 D4:XB:E4:FE:C6:6F domain source destination
192.168.2.102 B4:QB:Y4:FE:C6:6F domain source destination
192.168.2.103 B4:FB:P4:ZE:C6:6F domain source destination
192.168.2.104 B4:FB:E4:BE:P6:6F domain source destination
111.111.111.111 AA:BB:CC:DD:EE:FF domain source destination

$ cat found.devices
192.168.2.190 => D4:XB:E4:FE:C6:6F
192.168.2.102 => B4:QB:Y4:FE:C6:6F
192.168.2.200 => B4:FB:P4:ZE:C6:6F
192.168.2.104 => B4:FB:E4:BE:P6:6F
222.222.222.222 => FF:EE:CC:BB:AA:11

一个awk想法:

$ cat ip.awk
FNR==NR  { ip[]=; dsd[]= FS  FS ; next }
 in ip { ip[]= }
END      { for (mac in ip) print ip[mac],dsd[mac] }

运行 针对我们的文件:

$ awk -f ip.awk known.targets found.devices
192.168.2.200 domain source destination
192.168.2.190 domain source destination
192.168.2.104 domain source destination
111.111.111.111 domain source destination
192.168.2.102 domain source destination

将其提供给 while 循环:

while read ip hostname source destination
do
    echo "${ip} : ${hostname} : ${source} : ${destination}"
done < <(awk -f ip.awk known.targets found.devices)

这会生成:

192.168.2.200 : domain : source : destination
192.168.2.190 : domain : source : destination
192.168.2.104 : domain : source : destination
111.111.111.111 : domain : source : destination
192.168.2.102 : domain : source : destination

试试这个纯 Bash 代码:

declare -A found_mac2ip
while read -r ip _ mac; do
    [[ -n $mac ]] && found_mac2ip[$mac]=$ip
done <'found.devices'

while read -r ip mac domain source destination; do
    ip=${found_mac2ip[$mac]-$ip}
    # ... DO BACKUP FOR $ip ...
done <'known.targets'
  • 它首先建立一个Bash关联数组映射发现mac地址到ip地址。
  • 然后循环遍历 known.targets 文件,对于每个 mac 地址,它使用 known.targets 文件中的 IP 地址(如果其中列出了 mac 地址) .否则它使用从 known.targets 文件中读取的 IP 地址。

也可以通过直接从 nmap 输出而不是从 `found.devices' 文件中获取来提取“找到的”MAC 和 IP 地址信息。这个替代版本的代码是这样做的:

declare -A found_mac2ip
nmap_output=$(sudo nmap -n -sP 192.168.2.0/24)
while IFS=$' \t\n()' read -r f1 f2 f3 f4 f5 _; do
    [[ "$f1 $f2 $f3 $f4" == 'Nmap scan report for' ]] && ip=$f5
    [[ "$f1 $f2" == 'MAC Address:' ]] && found_mac2ip[$f3]=$ip
done <<<"$nmap_output"

while read -r ip mac domain source destination; do
    ip=${found_mac2ip[$mac]-$ip}
    # ... DO BACKUP FOR $ip ...
done <'known.targets'