如何检测网线/连接器的物理连接状态?

发布于 2024-07-18 14:09:30 字数 480 浏览 6 评论 0原文

在 Linux 环境中,我需要检测 RJ45 连接器与其插座的物理连接或断开状态。 最好仅使用 BASH 脚本。

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

  1. 使用“ifconfig” - 因为可能已连接网络电缆,但网络未正确配置或当前未启动。
  2. Ping 主机 - 因为该产品将位于使用未知网络配置和未知主机的 LAN 中。

/proc 文件系统中是否没有可以使用的状态(其他所有内容都在那里)?

Linux 世界怎么会有自己版本的 Windows 气泡,从图标托盘中弹出,表明您刚刚拔掉了网络电缆?


Kent Fredriclothar,你们的回答都满足了我的需要...非常感谢! 我会使用哪一个...我仍然不知道。

我想我不能把你们俩都列为正确答案吗? 我选择其中之一对你来说可能是公平的。 我猜抛硬币? 再次感谢!

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.

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.

Isn't there some state which can be used in the /proc file system (everything else is in there)?

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?


Kent Fredric and lothar, both of your answers satisfy my need... thanks a lot! Which one I'll use... I still don't know.

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

最后的乘客 2024-07-25 14:09:31

我使用此命令来检查电线

cd /sys/class/net/
grep "" eth0/operstate

是否已连接:结果是向上还是向下。 有时显示未知,那么你需要检查

eth0/carrier

它显示0或1

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

各自安好 2024-07-25 14:09:31

有两个守护进程可以检测这些事件:

ifplugdnetplugd

There exists two daemons that detect these events:

ifplugd and netplugd

柳若烟 2024-07-25 14:09:31

大多数现代 Linux 发行版都使用 NetworkManager 来实现此目的。 您可以使用 D-BUS 来监听事件。

如果您想要一个命令行工具来检查状态,您也可以使用mii-tool,因为您考虑的是以太网。

Most modern Linux distributions use NetworkManager for this. You could use D-BUS to listen for the events.

If you want a command-line tool to check the status, you can also use mii-tool, given that you have Ethernet in mind.

娇妻 2024-07-25 14:09:31

一些精度和技巧

  1. 我以普通用户(不是root)的身份完成所有这些

  2. dmesg获取信息

    使用dmesg是查询系统当前状态的第一件事:

    <前><代码>dmesg | sed '/eth.*链接为/h;${x;p};d'

    可以回答如下:

    [936536.904154] e1000e: eth0 NIC 链路已关闭 
      

    [936555.596870] e1000e:eth0 NIC 链路已启动 100 Mbps 全双工,流量控制:Rx/Tx 
      

    根据状态,消息可能会因所使用的硬件和驱动程序而异。

    注意:这可以通过编写 dmesg|grep eth.*Link.is|tail -n1 但我更喜欢使用 sed

    <前><代码>dmesg | sed '/eth.*链接为/h;${x;s/^.*链接为//;p};d'
    高达 100 Mbps 全双工,流量控制:Rx/Tx

    dmesg | sed '/eth.*链接为/h;${x;s/^.*链接为//;p};d'
    向下

  3. 围绕 /sys 伪文件系统进行测试

    /sys下读取或写入可能会破坏您的系统,特别是如果以root身份运行! 您已收到警告;-)

    这是一种池化方法,而不是真正的事件跟踪

    <前><代码>cd /tmp
    grep -H 。 /sys/class/net/eth0/* 2>/dev/null>ethstate
    尽管 ! 读-t 1;做
    grep -H 。 /sys/class/net/eth0/* 2>/dev/null | /sys/class/net/eth0/* 2>/dev/null |
    diff -u ethstate - | 差异
    三通>(补丁-p0)|
    查找^+
    完毕

    可以呈现类似的内容(一旦拔下插头并重新插回,具体取决于):

    <前><代码>+++ - 2016-11-18 14:18:29.577094838 +0100
    +/sys/class/net/eth0/运营商:0
    +/sys/class/net/eth0/Carrier_changes:9
    +/sys/class/net/eth0/duplex:未知
    +/sys/class/net/eth0/operstate:down
    +/sys/class/net/eth0/速度:-1
    +++ - 2016-11-18 14:18:48.771581903 +0100
    +/sys/class/net/eth0/运营商:1
    +/sys/class/net/eth0/Carrier_changes:10
    +/sys/class/net/eth0/duplex:full
    +/sys/class/net/eth0/operstate:up
    +/sys/class/net/eth0/速度:100

    (按Enter退出循环)

    注意:这需要安装补丁

  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 接口

Some precisions and tricks

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

  2. Grab infos from dmesg

    Using dmesg is one of the 1st things to do for inquiring current state of 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 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 /sys pseudo 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 Enter to exit loop)

    Nota: This require patch to be installed.

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

    Depending on Linux Installation, you could add if-up and if-down scripts to be able to react to this kind of events.

    On Debian based (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.

尝蛊 2024-07-25 14:09:31

不知何故,如果你想在命令“ifconfig eth0 down”之后检查以太网电缆是否插入Linux。
我找到一个解决方案:
使用 ethtool 工具。

#ethtool -t eth0
The test result is PASS
The test extra info:
Register test  (offline)         0
Eeprom test    (offline)         0
Interrupt test (offline)         0
Loopback test  (offline)         0
Link test   (on/offline)         0

如果电缆已连接,则链路测试为 0,否则为 1。

Somehow if you want to check if the ethernet cable plugged in linux after the commend:" ifconfig eth0 down".
I find a solution:
use the ethtool tool.

#ethtool -t eth0
The test result is PASS
The test extra info:
Register test  (offline)         0
Eeprom test    (offline)         0
Interrupt test (offline)         0
Loopback test  (offline)         0
Link test   (on/offline)         0

if cable is connected,link test is 0,otherwise is 1.

原来是傀儡 2024-07-25 14:09:31

在 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

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

/sys/class/net/(interface name here)/operstate
#you can also put watch 
watch -d -n -1 /sys/class/net/(interface name here)/operstate
野の 2024-07-25 14:09:31

可以使用ifconfig。

# ifconfig eth0 up
# ifconfig eth0

如果条目显示 RUNNING,则该接口已物理连接。 无论是否配置接口,都会显示此信息。

这只是获取 /sys/class/net/eth0/operstate 中信息的另一种方法。

You can use ifconfig.

# ifconfig eth0 up
# ifconfig eth0

If the entry shows RUNNING, the interface is physically connected. This will be shown regardless if the interface is configured.

This is just another way to get the information in /sys/class/net/eth0/operstate.

没有心的人 2024-07-25 14:09:31
tail -f /var/log/syslog | grep -E 'link (up|down)'

或者对我来说更快:

tail -f /var/log/syslog | grep 'link \(up\|down\)'

它将监听系统日志文件。

结果(如果断开连接,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
tail -f /var/log/syslog | grep -E 'link (up|down)'

or for me faster gets:

tail -f /var/log/syslog | grep 'link \(up\|down\)'

It will listen to the syslog file.

Result (if disconnect and after 4 seconds connect again):

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
陪你到最终 2024-07-25 14:09:31

此命令检查“ip a”命令的第二个接口中的“state UP”。 我已经检查了 2 台运行 wifi 的计算机,列出的第二台是有线以太网。 如果您想检查不同的接口,只需将下面命令中的“2”更改为正确的索引位置即可。

astate=`ip a | grep -E -o -m 1 "2:.*state UP"`  
if [ -n "$astate" ]; then
   echo 'cable is on'
else
   echo 'cable is off'
fi

This command checks for "state UP" in the 2nd interface of the "ip a" command. I have checked in 2 computers running wifi, the 2nd listed is the cable ethernet. Case you want to check a different interface, just change the "2" in the command below to be the correct index position.

astate=`ip a | grep -E -o -m 1 "2:.*state UP"`  
if [ -n "$astate" ]; then
   echo 'cable is on'
else
   echo 'cable is off'
fi
烧了回忆取暖 2024-07-25 14:09:31

在 OpenWRT 上,至少对我来说,可靠地执行此操作的唯一方法是运行以下命令:

# Get switch name
swconfig list

# assuming switch name is "switch0"
swconfig dev switch0 show | grep link:

# Possible output
root@OpenWrt:~# swconfig dev switch0 show | grep link:
        link: port:0 link:up speed:1000baseT full-duplex txflow rxflow
        link: port:1 link:up speed:1000baseT full-duplex txflow rxflow eee100 eee1000 auto
        link: port:2 link:up speed:1000baseT full-duplex txflow rxflow eee100 eee1000 auto
        link: port:3 link:down
        link: port:4 link:up speed:1000baseT full-duplex eee100 eee1000 auto
        link: port:5 link:down
        link: port:6 link:up speed:1000baseT full-duplex txflow rxflow

这将在交换机的每个端口上显示“link:down”或“link:up”。

On OpenWRT the only way to reliably do this, at least for me, is by running these commands:

# Get switch name
swconfig list

# assuming switch name is "switch0"
swconfig dev switch0 show | grep link:

# Possible output
root@OpenWrt:~# swconfig dev switch0 show | grep link:
        link: port:0 link:up speed:1000baseT full-duplex txflow rxflow
        link: port:1 link:up speed:1000baseT full-duplex txflow rxflow eee100 eee1000 auto
        link: port:2 link:up speed:1000baseT full-duplex txflow rxflow eee100 eee1000 auto
        link: port:3 link:down
        link: port:4 link:up speed:1000baseT full-duplex eee100 eee1000 auto
        link: port:5 link:down
        link: port:6 link:up speed:1000baseT full-duplex txflow rxflow

This will show either "link:down" or "link:up" on every port of your switch.

失去的东西太少 2024-07-25 14:09:31

我使用 OpenWRT 增强型设备作为中继器(添加了虚拟以太网和无线局域网功能),发现 /sys/class/net/eth0 运营商和 opstate 值不可靠。 我也玩过 /sys/class/net/eth0.1 和 /sys/class/net/eth0.2 以及(至少我发现)没有可靠的方法来检测某些东西是否已物理插入并在任何设备上进行通信以太网端口。 我想出了一种有点粗略但看似可靠的方法来检测至少自上次重新启动/开机状态以来是否插入了任何东西(在我的情况下,它的工作原理与我所需要的完全一样)。

ifconfig eth0 | grep -o 'RX packets:[0-9]*' | grep -o '[0-9]*'

如果没有插入任何东西并且有东西 > >,您将得到 0。 如果自上次开机或重新启动周期以来已插入任何设备(即使已插入并已移除),则为 0。

希望这至少可以帮助某人!

I was using my OpenWRT enhanced device as a repeater (which adds virtual ethernet and wireless lan capabilities) and found that the /sys/class/net/eth0 carrier and opstate values were unreliable. I played around with /sys/class/net/eth0.1 and /sys/class/net/eth0.2 as well with (at least to my finding) no reliable way to detect that something was physically plugged in and talking on any of the ethernet ports. I figured out a bit crude but seemingly reliable way to detect if anything had been plugged in since the last reboot/poweron state at least (which worked exactly as I needed it to in my case).

ifconfig eth0 | grep -o 'RX packets:[0-9]*' | grep -o '[0-9]*'

You'll get a 0 if nothing has been plugged in and something > 0 if anything has been plugged in (even if it was plugged in and since removed) since the last power on or reboot cycle.

Hope this helps somebody out at least!

暖伴 2024-07-25 14:09:30

你想看看

/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/* 

这形成了一个很好的列表键:值对。

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.

盗梦空间 2024-07-25 14:09:30

您可以使用 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

You can use 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:

$ sudo ethtool eth0 | grep Link
    Link detected: yes
心凉怎暖 2024-07-25 14:09:30

使用“ip Monitor”获取实时链接状态变化。

Use 'ip monitor' to get REAL TIME link state changes.

随心而道 2024-07-25 14:09:30

cat /sys/class/net/ethX 是迄今为止最简单的方法。

但接口必须处于启动状态,否则您将收到无效参数错误。

所以首先:

ifconfig ethX up

然后:

cat /sys/class/net/ethX

cat /sys/class/net/ethX is by far the easiest method.

The interface has to be up though, else you will get an invalid argument error.

So first:

ifconfig ethX up

Then:

cat /sys/class/net/ethX
面如桃花 2024-07-25 14:09:30

在低级别上,可以使用 捕获这些事件rtnetlink 套接字,没有任何轮询。 旁注:如果您使用 rtnetlink,则必须与 udev 一起工作,否则当 udev 重命名新的网络接口时,您的程序可能会感到困惑。

使用 shell 脚本进行网络配置的问题在于 shell 脚本对于事件处理来说很糟糕(例如插入和拔出网线)。 如果您需要更强大的东西,请查看我的 NCD 编程语言,这是一种专为网络配置而设计的编程语言。

例如,一个简单的 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 :)
}

在内部,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 地址将自动删除。

On the low level, these events can be caught using rtnetlink sockets, 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.

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.

For example, a simple NCD script that will print "cable in" and "cable out" to stdout (assuming the interface is already up):

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)

The idea of NCD is that you use it exclusively to configure the network, so normally, configuration commands would come in between, such as:

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文