如何检测网线/连接器的物理连接状态?
在Linux环境中,我需要检测RJ45连接器到其sockets的物理连接或断开状态。 最好只使用BASH脚本。
以下在其他网站上提出的解决scheme不适用于此目的:
- 使用'ifconfig' – 因为可能连接了networking电缆,但是networkingconfiguration不正确或者当前没有连接。
- Ping主机 – 因为产品将在使用未知networkingconfiguration和未知主机的LAN内。
是不是有一些可以在/ proc文件系统中使用的状态(一切都在那里)?
Linux世界如何假设自己版本的Windows泡泡从图标托盘popup,表明您刚刚拔掉了网线?
肯特弗雷德里克和洛塔尔 ,你的答案都满足我的需要…非常感谢! 我将使用哪一个…我仍然不知道。
我想我不能把你们俩都当成正确的答案吗? 对我来说,我确实select了一个。 翻转一枚硬币,我猜? 再次,谢谢!
你想看看里面的节点
/ SYS /class/网/
我对我的实验:
电线插入:
eth0/carrier:1 eth0/operstate:unknown
电线已移除:
eth0/carrier:0 eth0/operstate:down
电线再次插入:
eth0/operstate:up eth0/carrier:1
侧面戏法:一次收获所有属性的简单方法:
grep "" eth0/*
这形成了一个很好的key:value
对列表。
你可以使用ethtool :
$ sudo ethtool eth0 Settings for eth0: Supported ports: [ TP ] Supported link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full Supports auto-negotiation: Yes Advertised link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full Advertised auto-negotiation: Yes Speed: 1000Mb/s Duplex: Full Port: Twisted Pair PHYAD: 0 Transceiver: internal Auto-negotiation: on Supports Wake-on: umbg Wake-on: g Current message level: 0x00000007 (7) Link detected: yes
要仅获得链接状态,您可以使用grep:
$ sudo ethtool eth0 | grep Link Link detected: yes
使用“ip monitor”获取实时链接状态更改。
cat /sys/class/net/ethX
是迄今为止最简单的方法。
界面必须要起来,否则你会得到一个无效的参数错误。
所以第一:
ifconfig ethX up
然后:
cat /sys/class/net/ethX
在低级别上,可以使用rtnetlink套接字捕获这些事件,而不进行任何轮询。 注意:如果你使用rtnetlink,你必须和udev一起工作,否则你的程序会在udev重新命名一个新的networking接口的时候感到困惑。
使用shell脚本进行networkingconfiguration的问题在于, shell脚本对于事件处理 (例如networking电缆被插入和拔出) 是非常糟糕的 。 如果您需要更强大的function,请查看我的NCD编程语言 ,一种专为networkingconfigurationdevise的编程语言。
例如,一个简单的NCD脚本将打印“电缆input”和“电缆输出”到标准输出(假设接口已经打开):
process foo { # Wait for device to appear and be configured by udev. net.backend.waitdevice("eth0"); # Wait for cable to be plugged in. net.backend.waitlink("eth0"); # Print "cable in" when we reach this point, and "cable out" # when we regress. println("cable in"); # or pop_bubble("Network cable in."); rprintln("cable out"); # or rpop_bubble("Network cable out!"); # just joking, there's no pop_bubble() in NCD yet :) }
(在内部, net.backend.waitlink()
使用rtnetlink,而net.backend.waitdevice()
使用udev)
NCD的思想是你专门用它来configurationnetworking,所以通常configuration命令会在两者之间传递,比如:
process foo { # Wait for device to appear and be configured by udev. net.backend.waitdevice("eth0"); # Set device up. net.up("eth0"); # Wait for cable to be plugged in. net.backend.waitlink("eth0"); # Add IP address to device. net.ipv4.addr("eth0", "192.168.1.61", "24"); }
重要的一点是,执行是可以倒退的 。 在第二个例子中,例如,如果电缆被拔出,IP地址将被自动删除。
有两个守护进程检测这些事件:
ifplugd和netplugd
大多数现代Linux发行版都使用NetworkManager 。 您可以使用D-BUS来收听事件。
如果你想要一个命令行工具来检查状态,你也可以使用mii-tool
,因为你有以太网。
一些精确度和技巧
-
我做这一切正常用户 (不是根 )
-
从
dmesg
信息使用
dmesg
是查询系统当前状态的第一件事情:dmesg | sed '/eth.*Link is/h;${x;p};d'
可以回答这样的事情:
[936536.904154] e1000e: eth0 NIC Link is Down
要么
[936555.596870] e1000e: eth0 NIC Link is Up 100 Mbps Full Duplex, Flow Control: Rx/Tx
根据状态,消息可能会根据所使用的硬件和驱动程序而有所不同
注意:这可以通过写
dmesg|grep eth.*Link.is|tail -n1
但我更喜欢使用sed
。dmesg | sed '/eth.*Link is/h;${x;s/^.*Link is //;p};d' Up 100 Mbps Full Duplex, Flow Control: Rx/Tx dmesg | sed '/eth.*Link is/h;${x;s/^.*Link is //;p};d' Down
-
testing
/sys
伪文件系统读/写在
/sys
可能会破坏你的系统,特别是以root身份运行的时候! 你已经被警告;-)这是一个池化的方法,而不是一个真正的事件跟踪 。
cd /tmp grep -H . /sys/class/net/eth0/* 2>/dev/null >ethstate while ! read -t 1;do grep -H . /sys/class/net/eth0/* 2>/dev/null | diff -u ethstate - | tee >(patch -p0) | grep ^+ done
可以呈现类似的东西(一旦你已经拔下插头,取决于):
+++ - 2016-11-18 14:18:29.577094838 +0100 +/sys/class/net/eth0/carrier:0 +/sys/class/net/eth0/carrier_changes:9 +/sys/class/net/eth0/duplex:unknown +/sys/class/net/eth0/operstate:down +/sys/class/net/eth0/speed:-1 +++ - 2016-11-18 14:18:48.771581903 +0100 +/sys/class/net/eth0/carrier:1 +/sys/class/net/eth0/carrier_changes:10 +/sys/class/net/eth0/duplex:full +/sys/class/net/eth0/operstate:up +/sys/class/net/eth0/speed:100
( 按Enter键退出循环)
注意:这需要安装
patch
程序。 -
好的,这件事一定已经有了…
根据Linux安装 ,您可以添加
if-up
和if-down
脚本来对这种事件做出反应。在Debian的基础上(如Ubuntu ),你可以存储你的脚本
/etc/network/if-down.d /etc/network/if-post-down.d /etc/network/if-pre-up.d /etc/network/if-up.d
看到更多的信息
man interfaces
。
我使用这个命令来检查一条连线:
cd /sys/class/net/ grep "" eth0/operstate
如果结果会上升或下降。 有时它显示不明,那么你需要检查
eth0/carrier
它显示0或1
在拱门的Linux。 (我不知道其他发行版),你可以查看operstate。 如果连接或closures,则显示如果不是operstate生活在其上
/sys/class/net/(interface name here)/operstate #you can also put watch watch -d -n -1 /sys/class/net/(interface name here)/operstate