近日工作中有一个根据设备IP地址获取对应MAC地址的需求,但IP属于不同网段,也没有访问三层网络设备的权限,通过一个Shell脚本曲线达到目的。
以下代码基于bash,需要安装“sshpass”命令,执行时传参“待处理文件”、“SSH连接密码”、“SSH连接端口号”。“待处理文件”格式为记录设备名称、主机IP、连接设备IP三列。
例:bash getmac.sh iplist.txt 123456 22
#!/bin/bash标签:网段,地址,echo,v1,MAC,awk,print,txt From: https://blog.51cto.com/u_10248921/6091443
v1=${1}
p1=${2}
p2=${3}
f1='host_fail.txt'
f2='host_mac.txt'
f3='red_fail.txt'
f4='red_mac.txt'
#转换文件编码格式
if [ `file ./${v1} | awk -F ' ' '{print $2}'` == "ISO-8859" ];then
iconv -f GB2312 -t UTF-8 ./${v1} -o ./${v1}
fi
#生成结果文件
touch ./${f1}
touch ./${f3}
sed -i "s/\r//" ./${v1}
head -1 ./${v1} | awk -F ' ' '{print $1,$2}' > ./${f1}
cp -af ./${f1} ./${f2}
sed -i "s/$/\tMAC/g" ./${f2}
head -1 ./${v1} | awk -F ' ' '{print $1,$3}' > ./${f3}
cp -af ./${f3} ./${f4}
sed -i "s/$/\tMAC/g" ./${f4}
#生成处理数据临时文件
sed 1d ./${v1} >/tmp/tmpfile.txt
#修改for循环取值分隔符为换行符,默认为空格。
z1=$IFS
IFS=$'\n'
for line in $(cat /tmp/tmpfile.txt);do
ip1=`echo ${line}|awk -F ' ' '{print $2}'`
ip2=`echo ${line}|awk -F ' ' '{print $3}'`
y1=`echo ${line}|awk -F ' ' '{print $1,$2}'`
y2=`echo ${line}|awk -F ' ' '{print $1,$3}'`
/bin/ping -c 3 -W 3 -i 0.3 ${ip1} >/dev/null
x1=${?}
/bin/ping -c 3 -W 3 -i 0.3 ${ip2} >/dev/null
x2=${?}
#获取主机MAC地址
if [ ${x1} -eq 0 ];then
mac1=`sshpass -p ${p1} ssh -o StrictHostKeyChecking=no -p ${p2} root@${ip1} cat /sys/class/net/eth0/address`
echo '***************************'
echo $mac1
echo '***************************'
if [ $mac1 ];then
echo -e "${y1}\t${mac1}" >>./${f2}
else
echo -e "${y1}\tGet_MAC_Fail!" >>./${f2}
fi
else
echo ${y1} >> ./${f1}
fi
#获取主机连接设备的MAC地址
if [ ${x2} -ne 0 ];then
echo ${y2} >> ./${f3}
elif [ ${x1} -eq 0 ];then
sshpass -p ${p1} ssh -o StrictHostKeyChecking=no -p ${p2} root@${ip1} ping -c 3 ${ip2} >/dev/null
mac2=`sshpass -p ${p1} ssh -o StrictHostKeyChecking=no -p ${p2} root@${ip1} arp ${ip2}`
echo '***************************'
echo $mac2
echo '***************************'
mac2=`echo ${mac2} | awk -F ' ' '{print $9}'`
if [ ${#mac2} -eq 17 ];then
echo -e "${y2}\t${mac2}" >>./${f4}
else
echo -e "${y2}\tGet_MAC_Fail!" >>./${f4}
fi
fi
done
IFS=${z1}
#生成一份Windows系统下的GB2312编码格式
for i in ${f1} ${f2} ${f3} ${f4};do
sed -i "s/ /\t/g" ./${i}
iconv -f UTF-8 -t GB2312 ./${i} -o ./${i%.*}_GB2312.txt
done
rm -f /tmp/tmpfile.txt