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

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

  1. 使用'ifconfig' - 因为网络电缆可能已连接但网络未正确配置或当前未正常运行。
  2. Ping主机 - 因为产品将位于使用未知网络配置和未知主机的LAN中。
  3. 是否有某些状态可以在/ 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

一些精确度和技巧

  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
    

    取决于状态,消息可能因使用的硬件和驱动程序而异。

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

    (点击输入退出循环)

    Nota:这需要安装 patch

  4. 很好,一定有关于此的事情......

    取决于 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,如果已插入任何内容(即使已插入并已移除),因为上次开机或重启循环。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top