Как определить физическое состояние подключенного сетевого кабеля / разъема? - PullRequest
133 голосов
/ 30 апреля 2009

В среде Linux мне нужно определить физическое состояние подключения или отключения разъема RJ45 к его разъему. Предпочтительно использовать только сценарии BASH.

Следующие решения, которые были предложены на других сайтах, НЕ работают для этой цели:

  1. Использование 'ifconfig' - поскольку сетевой кабель может быть подключен, но сеть не настроена должным образом или в данный момент не работает.
  2. Проверка связи с хостом - поскольку продукт будет находиться в локальной сети с использованием неизвестной конфигурации сети и неизвестных хостов.

Не существует ли какого-либо состояния, которое можно использовать в файловой системе / proc (все остальное там)?

Как в мире Linux предполагают наличие собственной версии пузыря Windows, которая выскакивает из панели значков, показывая, что вы только что отсоединили сетевой кабель?


Кент Фредрик и Лотар , оба ваших ответа удовлетворяют мою потребность ... большое спасибо! Какой я буду использовать ... Я до сих пор не знаю.

Думаю, я не могу поставить вас обоих за правильный ответ? И это, вероятно, справедливо для вас, что я выберу один. Я полагаю, бросить монетку? Еще раз спасибо!

Ответы [ 13 ]

204 голосов
/ 30 апреля 2009

Вы хотите посмотреть на узлы в

/sys/class/net/

Я экспериментировал с моим:

Провод подключен:

eth0/carrier:1
eth0/operstate:unknown

Проволока удалена:

eth0/carrier:0
eth0/operstate:down

Провод снова подключен:

eth0/carrier:1
eth0/operstate:up

Боковой трюк: простой сбор всех свойств:

grep "" eth0/* 

Это хороший список из key:value пар.

78 голосов
/ 30 апреля 2009

Вы можете использовать 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
24 голосов
/ 06 сентября 2012

Используйте 'ip monitor' для получения изменений состояния соединения в РЕАЛЬНОМ ВРЕМЕНИ.

17 голосов
/ 01 ноября 2011

cat /sys/class/net/ethX - безусловно, самый простой метод.

Интерфейс должен быть включен, иначе вы получите ошибку неверного аргумента.

Итак, сначала:

ifconfig ethX up

Тогда:

cat /sys/class/net/ethX
8 голосов
/ 01 ноября 2011

На низком уровне эти события могут быть перехвачены с помощью сокетов rtnetlink без опроса. Примечание: если вы используете rtnetlink, вам придется работать вместе с udev, или ваша программа может запутаться, когда udev переименует новый сетевой интерфейс.

Проблема с настройкой сети при помощи сценариев оболочки заключается в том, что сценарии оболочки ужасны для обработки событий (например, при подключении и отключении сетевого кабеля). Если вам нужно что-то более мощное, взгляните на мой NCD язык программирования , язык программирования, разработанный для сетевых конфигураций.

Например, простой сценарий NCD, который будет печатать «кабель» и «кабель» на стандартный вывод (при условии, что интерфейс уже подключен):

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-адрес будет автоматически удален.

4 голосов
/ 30 августа 2013

Существует два демона, которые обнаруживают эти события:

ifplugd и netplugd

2 голосов
/ 18 ноября 2016

Некоторые точности и хитрости

  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
    

    (нажмите Введите для выхода из цикла)

    Примечание: для этого необходимо установить 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 для получения дополнительной информации.

2 голосов
/ 19 августа 2014

Я использую эту команду для проверки подключения провода:

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

Если результат будет вверх или вниз. Иногда показывает неизвестное, тогда нужно проверить

eth0/carrier

Показывает 0 или 1

2 голосов
/ 30 апреля 2009

В большинстве современных дистрибутивов Linux для этого используется NetworkManager . Вы можете использовать D-BUS для прослушивания событий.

Если вы хотите, чтобы инструмент командной строки проверял состояние, вы также можете использовать mii-tool, учитывая, что вы имеете в виду Ethernet.

1 голос
/ 01 февраля 2019
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
...