如何检测网络电缆/连接器的物理连接状态?
-
03-07-2019 - |
题
在Linux环境中,我需要检测RJ45连接器到其插槽的物理连接或断开状态。最好只使用BASH脚本。
以下在其他网站上提出的解决方案不能用于此目的:
- 使用'ifconfig' - 因为网络电缆可能已连接但网络未正确配置或当前未正常运行。
- Ping主机 - 因为产品将位于使用未知网络配置和未知主机的LAN中。 醇>
是否有某些状态可以在/ proc文件系统中使用(其他所有内容都在那里)?
Linux世界是如何设置自己的Windows泡泡版本,从图标托盘弹出,表明您刚刚拔掉了网线?
Kent Fredric 和 lothar ,您的两个答案都满足了我的需求......非常感谢!我将使用哪一个......我仍然不知道。
我想我不能把你们两个都当作正确的答案?对我来说,我选择一个可能是公平的。我猜是翻硬币吗?再次,谢谢!
解决方案
您想查看
中的节点/sys/class/net/
我在实验中尝试过:
插入电线:
eth0/carrier:1
eth0/operstate:unknown
删除电线:
eth0/carrier:0
eth0/operstate:down
再次接通电线:
eth0/carrier:1
eth0/operstate:up
Side Trick:轻松获取所有属性:
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
是目前最简单的方法。
接口必须是up,否则你会得到一个无效的参数错误。
首先:
ifconfig ethX up
然后:
cat /sys/class/net/ethX
在低级别,可以使用 rtnetlink 套接字,没有任何轮询。附注:如果您使用rtnetlink,则必须与udev一起工作,否则当udev重命名新的网络接口时,您的程序可能会感到困惑。
使用shell脚本进行网络配置的问题是 shell脚本对于事件处理非常糟糕(例如插入和拔出网络电缆)。如果您需要更强大的功能,请查看我的 NCD编程语言,为网络配置而设计的编程语言。
例如,一个简单的NCD脚本将打印“电缆输入”。和“电缆输出”到stdout(假设接口已经启动):
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的想法是你专门用它来配置网络,所以通常,配置命令介于两者之间,例如:
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
,因为您考虑到了以太网。
我使用此命令检查电线是否已连接:
cd /sys/class/net/
grep "" eth0/operstate
如果结果是向上或向下。有时它显示未知,那么你需要检查
eth0/carrier
显示0或1
一些精确度和技巧
-
我这样做是为了普通用户(不是 root )
-
从
获取信息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
取决于状态,消息可能因使用的硬件和驱动程序而异。
Nota:这可以写成
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
-
围绕
/ 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
(点击输入退出循环)
Nota:这需要安装
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
。
醇>
tail -f /var/log/syslog | grep -E 'link (up|down)'
或者对我来说更快得到:
tail -f /var/log/syslog | grep 'link \(up\|down\)'
它将侦听syslog文件。
结果(如果断开连接并再次连接4秒后):
Jan 31 13:21:09 user kernel: [19343.897157] r8169 0000:06:00.0 enp6s0: link down
Jan 31 13:21:13 user kernel: [19347.143506] r8169 0000:06:00.0 enp6s0: link up
在arch linux上。 (我不确定在其他发行版上)你可以查看operstate。如果没有,那么如果没有,那就会显示出连接或关闭
/sys/class/net/(interface name here)/operstate
#you can also put watch
watch -d -n -1 /sys/class/net/(interface name here)/operstate
你可以使用ifconfig。
# ifconfig eth0 up
# ifconfig eth0
如果条目显示RUNNING,则表示接口已物理连接。无论是否配置了接口,都会显示此信息。
这只是获取 / sys / class / net / eth0 / operstate
中信息的另一种方法。
我使用OpenWRT增强型设备作为转发器(增加了虚拟以太网和无线局域网功能),发现/ sys / class / net / eth0载体和opstate值不可靠。我玩了/sys/class/net/eth0.1和/sys/class/net/eth0.2以及(至少对我的发现)没有可靠的方法来检测物理插入的东西并在任何地方进行交谈以太网端口。我发现有点原始但看似可靠的方法来检测自上次重启/ poweron状态以来是否插入了任何东西(在我的情况下,它完全像我需要的那样工作)。
ifconfig eth0 | grep -o 'RX packets:[0-9]*' | grep -o '[0-9]*'
如果没有插入任何东西,你会得到一个0> 0,如果已插入任何内容(即使已插入并已移除),因为上次开机或重启循环。
希望这至少可以帮助某人!