2014-08-28 79 views
2

我使用以下命令获取arp表。我现在想要将本地主机的ip和MAC地址添加到输出中。我应该如何编写shell脚本?将localhost的IP和MAC地址添加到shell脚本中

arp | grep -v 'incomplete' | tail -n+2 | awk '{print $1"*"$4}' 

所以结果看起来像下面(它增加了IFACE和主机的ip ARP表项的每一行)

eno16777736 192.168.140.133 192.168.140.254,00:50:56:ef:2d:57 
eno16777736 192.168.140.133 192.168.140.2,00:50:56:ea:cf:bf 
+0

你打算如何处理多个网卡?另外,'ip addr show'通常是一个好方法。 – 2014-08-28 18:15:02

回答

3

在我的系统,我可以这样做:

arp | 
awk 'NR>1{mac[$NF]=mac[$NF]" "$3} END {for (iface in mac) print iface, mac[iface]}' | 
while read iface mac; do 
    inet=$(
     ifconfig "$iface" | 
     awk -v i=$iface '{for (j=1; j<NF; j++) if ($j == "inet") {print $(j+1); exit}}' 
    ) 
    echo $iface $inet ${mac// /,} 
done 
+0

但是如果你使用shell脚本,arp将会“找不到” – 2014-08-28 18:20:46

+1

所以使用完整路径,例如'/ usr/sbin/arp',或者做'PATH = $ PATH:/ usr/sbin' – 2014-08-28 18:22:08

+0

谢谢Glenn.It是非常接近我所需要的。我更新了预期结果的问题。 – 2014-08-29 06:08:49

0

获取本地接口的MAC和IP地址信息的最简单方法是'ifconfig'命令,通常位于'/ sbin/ifconfig'。 就我而言,我使用的为wlan0作为我的主界面:

# /sbin/ifconfig wlan0 
wlan0  Link encap:Ethernet HWaddr 86:75:30:9a:09:87 
      inet addr:10.20.30.40 Bcast:10.20.30.255 Mask:255.255.255.0 
      UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 
      RX packets:1276663 errors:0 dropped:0 overruns:0 frame:0 
      TX packets:820927 errors:0 dropped:0 overruns:0 carrier:0 
      collisions:0 txqueuelen:1000 
      RX bytes:1233280913 (1.2 GB) TX bytes:105410513 (105.4 MB) 

最简单的例子,以获得您想要的输出使用组合回波/ grep的/ SED/AWK:

echo $(/sbin/ifconfig wlan0 | \ 
grep -oE "(HWaddr\ |inet\ addr:)[0-9a-fA-F:\.]+" | \ 
sed 's/^\(HWaddr \|inet addr\:\)//') | \ 
awk '{print $2"*"$1}' 

简介:

在grep的使用“-o”选项将输出只有什么是行内的匹配,而不是线路本身。

'-E'告诉grep期望在匹配条件中使用“扩展正则表达式”。在这种情况下,我们正在查找以“HWaddr”或“inet addr:”开始的条目,然后是字符'0-9','a-z','A-Z','或''。

如果在那里结束该命令,则剩下两行看起来像“HWaddr 86:75:30:9a:09:87”和“inet addr:10.20.30.40”。

我们只需要MAC和IP地址,所以我们告诉sed从行首开始('^'表示开始)抛弃“HWaddr”和“inet addr:”。

通过将该命令封装在'$()'中捕获该输出的输出将使两行成为一行,并用空格分隔。将这个添加到'echo'命令允许我们使用awk用'*'替换空格,使得最终的输出类似于原始的'arp | awk'命令。

,我们还剩下什么是这样的:

# echo $(/sbin/ifconfig wlan0 | grep -oE "(HWaddr\ |inet\ addr:)[0-9a-fA-F:\.]+" | sed 's/^\(HWaddr \|inet addr\:\)//') | awk '{print $2"*"$1}' 
10.20.30.40*86:75:30:9a:09:87 

你也可以做到这一点在纯bash脚本,通过使用其内置的正则表达式引擎:

# IFS=$'\n' echo $(IFS=$'\n'; 
for LINE in $(ifconfig wlan0); 
do if [[ "${LINE}" =~ .*(HWaddr\ |inet\ addr:)([0-9a-fA-F\:\.]+) || "${LINE}" =~ .*inet\ addr:([\d\.]+) ]]; 
then echo ${BASH_REMATCH[2]}; 
fi; done) | \ 
awk '{print $2"*"$1}' 
172.16.17.40*a0:88:b4:78:65:04 

...但它更痛苦的解释:-P