我想通过使用ip地址从arp表中获取mac地址。目前我正在使用此命令
arp -a $ipAddress | awk '{print $4}'
此命令打印出我想要的内容。但我对此并不满意,我想知道是否有任何内置方式或更稳定的方法来做到这一点。
答案 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个“列”
享受!