Linux 如何检测网线/连接器的物理连接状态?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/808560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to detect the physical connected state of a network cable/connector?
提问by Jeach
In a Linux environment, I need to detect the physical connected or disconnected state of an RJ45 connector to its socket. Preferably using BASH scripting only.
在 Linux 环境中,我需要检测 RJ45 连接器与其插座的物理连接或断开状态。最好只使用 BASH 脚本。
The following solutions which have been proposed on other sites do NOT work for this purpose:
在其他网站上提出的以下解决方案不适用于此目的:
- Using 'ifconfig' - since a network cable may be connected but the network not properly configured or not currently up.
- Ping a host - since the product will be within a LAN using an unknown network configuration and unknown hosts.
- 使用'ifconfig' - 因为网络电缆可能已连接但网络未正确配置或当前未启动。
- Ping 主机 - 因为产品将位于使用未知网络配置和未知主机的 LAN 中。
Isn't there some state which can be used in the /proc file system (everything else is in there)?
是不是有一些状态可以在 /proc 文件系统中使用(其他所有东西都在那里)?
How is the Linux world suppose to have their own version of the Windows bubble that pop up from the icon tray indicating that you've just unplugged the network cable?
Linux 世界如何假设自己版本的 Windows 气泡从图标托盘中弹出,表明您刚刚拔掉了网线?
Kent Fredricand lothar, both of your answers satisfy my need... thanks a lot! Which one I'll use... I still don't know.
Kent Fredric和lothar,你的两个答案都满足了我的需要......非常感谢!我会用哪一个……我还是不知道。
I guess I can't put you both down as the correct answer? And its probably fair for you that I do choose one. Flip a coin I guess? Again, thanks!
我想我不能把你们俩都当作正确答案?我选择一个对你来说可能是公平的。我猜是抛硬币吗?再次感谢!
采纳答案by Kent Fredric
You want to look at the nodes in
你想查看节点
/sys/class/net/
I experimented with mine:
我用我的做了实验:
Wire Plugged in:
电线插入:
eth0/carrier:1
eth0/operstate:unknown
Wire Removed:
电线移除:
eth0/carrier:0
eth0/operstate:down
Wire Plugged in Again:
再次插入电线:
eth0/carrier:1
eth0/operstate:up
Side Trick: harvesting all properties at once the easy way:
小窍门:用简单的方法一次性收集所有属性:
grep "" eth0/*
This forms a nice list of key:value
pairs.
这形成了一个很好的key:value
对列表 。
回答by andri
Most modern Linux distributions use NetworkManagerfor this. You could use D-BUS to listen for the events.
大多数现代 Linux 发行版都为此使用NetworkManager。您可以使用 D-BUS 来监听事件。
If you want a command-line tool to check the status, you can also use mii-tool
, given that you have Ethernet in mind.
如果您想要一个命令行工具来检查状态,也可以使用mii-tool
,前提是您考虑到了以太网。
回答by lothar
You can use ethtool:
您可以使用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
To only get the Link status you can use grep:
要仅获取链接状态,您可以使用 grep:
$ sudo ethtool eth0 | grep Link
Link detected: yes
回答by Marco
cat /sys/class/net/ethX
is by far the easiest method.
cat /sys/class/net/ethX
是迄今为止最简单的方法。
The interface has to be up though, else you will get an invalid argument error.
但是接口必须是 up 的,否则你会得到一个无效的参数错误。
So first:
所以首先:
ifconfig ethX up
Then:
然后:
cat /sys/class/net/ethX
回答by Ambroz Bizjak
On the low level, these events can be caught using rtnetlinksockets, without any polling. Side note: if you use rtnetlink, you have to work together with udev, or your program may get confused when udev renames a new network interface.
在底层,可以使用rtnetlink套接字捕获这些事件,无需任何轮询。附注:如果你使用rtnetlink,你必须和udev一起工作,否则你的程序可能会在udev重命名一个新的网络接口时混淆。
The problem with doing network configurations with shell scripts is that shell scripts are terrible for event handling(such as a network cable being plugged in and out). If you need something more powerful, take a look at my NCD programming language, a programming language designed for network configurations.
使用 shell 脚本进行网络配置的问题在于,shell 脚本对于事件处理(例如插入和拔出网络电缆)来说非常糟糕。如果您需要更强大的功能,请查看我的NCD 编程语言,这是一种专为网络配置设计的编程语言。
For example, a simple NCD script that will print "cable in" and "cable out" to stdout (assuming the interface is already up):
例如,一个简单的 NCD 脚本会将“cable in”和“cable out”打印到 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 :)
}
(internally, net.backend.waitlink()
uses rtnetlink, and net.backend.waitdevice()
uses udev)
(在内部,net.backend.waitlink()
使用 rtnetlink,并net.backend.waitdevice()
使用 udev)
The idea of NCD is that you use it exclusively to configure the network, so normally, configuration commands would come in between, such as:
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");
}
The important part to note is that execution is allowed to regress; in the second example, for instance, if the cable is pulled out, the IP address will automatically be removed.
需要注意的重要部分是允许执行回退;例如,在第二个示例中,如果电缆被拔出,IP 地址将自动删除。
回答by Peter Quiring
Use 'ip monitor' to get REAL TIME link state changes.
使用“ip monitor”获取实时链接状态变化。
回答by German
There exists two daemons that detect these events:
存在两个检测这些事件的守护进程:
ifplugdand netplugd
ifplugd和netplugd
回答by Sarvar Nishonboev
I use this command to check a wire is connected:
我使用这个命令来检查电线是否连接:
cd /sys/class/net/
grep "" eth0/operstate
If the result will be up or down. Sometimes it shows unknown, then you need to check
如果结果是向上或向下。有时显示未知,则需要检查
eth0/carrier
It shows 0 or 1
它显示 0 或 1
回答by F. Hauri
Some precisions and tricks
一些精度和技巧
I do all this as normal user(not root)
Grab infos from
dmesg
Using
dmesg
is one of the 1st things to do for inquiring current stateof system:dmesg | sed '/eth.*Link is/h;${x;p};d'
could answer something like:
[936536.904154] e1000e: eth0 NIC Link is Down
or
[936555.596870] e1000e: eth0 NIC Link is Up 100 Mbps Full Duplex, Flow Control: Rx/Tx
depending on state, message could vary depending on hardware and drivers used.
Nota: this could by written
dmesg|grep eth.*Link.is|tail -n1
but I prefer usingsed
.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
Test around
/sys
pseudo filesystemReading or writting under
/sys
could break your system, especially if run as root! You've been warned ;-)This is a pooling method, not a real event tracking.
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
Could render something like (once you've unplugged and plugged back, depending ):
+++ - 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
(Hit Enterto exit loop)
Nota: This require
patch
to be installed.In fine, there must already be something about this...
Depending on Linux Installation, you could add
if-up
andif-down
scripts to be able to react to this kind of events.On Debianbased (like Ubuntu), you could store your scripts into
/etc/network/if-down.d /etc/network/if-post-down.d /etc/network/if-pre-up.d /etc/network/if-up.d
see
man interfaces
for more infos.
我以普通用户(不是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
根据状态,消息可能会因使用的硬件和驱动程序而异。
注意:这可以通过书面形式,
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
(点击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
更多信息。
回答by Skrmnghrd
on arch linux. (im not sure on other distros) you can view the operstate. which shows up if connected or down if not the operstate lives on
在 Arch Linux 上。(我不确定在其他发行版上)您可以查看操作状态。如果连接或关闭则显示如果操作状态不存在
/sys/class/net/(interface name here)/operstate
#you can also put watch
watch -d -n -1 /sys/class/net/(interface name here)/operstate