有没有更好的方法从arp表获取mac地址?

时间:2012-12-08 13:47:15

标签: linux algorithm bash awk arp

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

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

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

6 个答案:

答案 0 :(得分:5)

您可以使用/proc/net/arp解析awk文件:

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

但我不确定它是否更简单(但它保存了一个fork和一个子shell)。

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

while read ip _ _ mac _; do
    [[ "$ip" == "$ipAddress" ]] && break
done < /proc/net/arp
echo "$mac"

答案 1 :(得分:1)

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

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

manpage for the Linux ARP kernel module列出了几种操作或读取ARP标签的方法,ioctl可能是最简单的。

答案 2 :(得分: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

答案 3 :(得分: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地址”。

答案 4 :(得分: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打印匹配。

答案 5 :(得分:0)

您可以将此脚本用于编写脚本:

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

它的作用:

1)读/ proc / net / arp(stanart arp输出)

2)用[0-9]

搜索蜇伤

3)获取带有mac地址的第4个“列”

享受!