5

我想通过使用 ip 地址从 arp 表中获取一个 mac 地址。目前我正在使用这个命令

arp -a $ipAddress | awk '{print $4}'

这个命令打印我想要的。但我对此并不满意,我想知道是否有任何内置方式或更稳定的方式来做到这一点。

4

7 回答 7

5

您可以使用以下方法解析/proc/net/arp文件awk

awk "/^${ipAddress//./\.}\>/"' { print $4 }' /proc/net/arp

但我不确定它是否更简单(虽然它节省了一个叉子和一个子shell)。

如果你想要一个 100% 的 bash 解决方案:

while read ip _ _ mac _; do
    [[ "$ip" == "$ipAddress" ]] && break
done < /proc/net/arp
echo "$mac"
于 2012-12-08T14:01:41.667 回答
1

好吧,您可以编写一个程序(例如用 C 语言)来实际使用 ARP 协议(​​是的,我知道这是多余的,例如 ATM 机或 PIN 号)本身来获取信息,但这可能比简单的管道。

也许您应该更严格地检查您的舒适度,因为它可能会给您带来一些不必要的努力:-)

Linux ARP 内核模块的手册页列出了几种操作或读取 ARP 表的方法,ioctl可能是最简单的。

于 2012-12-08T13:50:21.327 回答
1

的输出arp -a取决于区域设置(即它随您的系统语言而变化)。因此,至少将其强制为默认语言环境可能是一个好主意:

LC_ALL=C arp -a $ipAddress | awk '{print $4}'

但是,我和您一样担心 的输出arp -a不应该被解析。如果您的程序仅限于 linux 系统,另一种选择是解析文件/proc/net/arp。该文件由内核导出,并且是 arp 本身解析以获取其信息的文件。该文件的格式在手册页 proc(5) 中进行了描述,请参阅man 5 proc. 这可以使用 awk 轻松完成:

awk '$1==IPADDRESS {print $4}' /proc/net/arp
于 2012-12-08T14:01:19.043 回答
0

这是一个 awk + ​​sed 解决方案,它不假定列号始终为 4。

#!/bin/bash

cat /proc/net/arp |\
    # remove space from column headers
    sed 's/\([^ ]\)[ ]\([^ ]\)/\1_\2/g' |\
    # find HW_address column number and/or print that column
    awk '{
        if ( !column ) {
            for (i = 1; i <= NF; i++ ) {
                if ( $i ~ /HW_address/ ) { column=i }
            };
            print $column
         }
         else {
            print $column
         }
    }'

这里仍然有一些脆弱的假设,例如列名是“HW 地址”。

于 2012-12-09T03:08:55.217 回答
0

更新,移除了 PIPE

sed -nr 's/^'${ipAddress//./\.}'.*(([0-9A-Za-z]{2}:){5}[0-9A-Za-z]{2}).*$/\1/p' /proc/net/arp

非固定柱解决方案;

arp -a $ipAddress | sed -n 's/^.*\(\([0-9A-Z]\{2\}:\)\{5\}[0-9A-Z]\{2\}\).*$/\1/p'

解释

  • ^.*- 匹配字符串的开头,^后跟任何字符.*
  • [0-9A-Z]\{2\}:- 匹配任何数字字母数字字符两次,后跟冒号。
  • \([0-9A-Z]\{2\}:\)\{5\}( )- 匹配五次之间的模式。
  • [0-9A-Z]\{2\}- 匹配任何数字字母数字字符两次。
  • .*$- 匹配任何字符零次或多次,.*直到字符串结束$
  • \1/p- 返回捕获模式 1 /p打印匹配项。
于 2012-12-09T05:46:46.293 回答
0

您可以将其用于脚本:

awk ' $1~/[[:digit:]]/ {print $4}' /proc/net/arp

它的作用:

  1. 读取 /proc/net/arp(标准 arp 输出)

  2. 搜索带有 [0-9] 的字符串

  3. 使用 mac 地址获取第 4 个“列”

享受!

于 2016-02-22T15:36:54.713 回答
0

我更喜欢使用该arping命令来显式查询某个 IP 地址的 MAC(这也会更新本地 ARP 缓存):

 arping -c 1 192.168.2.24 | grep -Eo "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]"

查找是否存在两个或多个使用相同 IP 地址的主机(添加 -D 选项)或使用简单脚本检查本地 VLAN 中使用的当前 IP 地址非常有用,例如:

for i in $(seq 1 254); do 
    IP="192.168.5.$i"
    MAC=$(arping -c 1 $IP | grep -Eo "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]")
    if [ "$MAC" ] ; then
        echo "$IP $MAC"
    fi
done

请注意,这种arping方式无法检测到本地主机的 IP 地址(但我们可以在脚本中添加检查以显示它是否存在于范围内)。

有几个版本的arping选项和输出略有不同。在 Linux Ubuntu 中,包iputils-arping中有一个,包 arping中有另一个

注意:要回答问题而不是问题,过滤/proc/net/arp时必须使用确保完全匹配的正则表达式,例如以空格结束表达式(否则,在此示例中,如果存在,它还将显示 2.240-2.249 地址):

ipaddress="192.168.2.24"
grep "^${ipaddress} " /proc/net/arp | grep -Eo "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]")
于 2021-12-16T23:08:22.463 回答