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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:15:47  来源:igfitidea点击:

How to detect the physical connected state of a network cable/connector?

linuxnetworkingconnectiondetection

提问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:

在其他网站上提出的以下解决方案不适用于此目的:

  1. Using 'ifconfig' - since a network cable may be connected but the network not properly configured or not currently up.
  2. Ping a host - since the product will be within a LAN using an unknown network configuration and unknown hosts.
  1. 使用'ifconfig' - 因为网络电缆可能已连接但网络未正确配置或当前未启动。
  2. 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 Fredriclothar,你的两个答案都满足了我的需要......非常感谢!我会用哪一个……我还是不知道。

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:valuepairs.

这形成了一个很好的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/ethXis 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

ifplugdnetplugd

回答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

一些精度和技巧

  1. I do all this as normal user(not root)

  2. Grab infos from dmesg

    Using dmesgis 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 -n1but I prefer using 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
    
  3. Test around /syspseudo filesystem

    Reading or writting under /syscould 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 patchto be installed.

  4. In fine, there must already be something about this...

    Depending on Linux Installation, you could add if-upand if-downscripts 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 interfacesfor more infos.

  1. 我以普通用户(不是root)身份执行所有这些操作

  2. 从中获取信息 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
    
  3. 测试/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安装。

  4. 好吧,这件事一定已经有了……

    根据Linux安装,您可以添加if-upif-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