linux check - Как определить физическое состояние сетевого кабеля / разъема?




network test (9)

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

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

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

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

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

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

Наверное, я не могу поставить вас обоих как правильный ответ? И это, вероятно, справедливо для вас, что я выбираю его. Поверните монетку, я думаю? Опять же, спасибо!


Answers

На низком уровне эти события можно поймать с rtnetlink гнезд 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-адрес будет автоматически удален.


Некоторые исправления и трюки

  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 pseudo

    Чтение или написание под /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-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 для получения дополнительной информации.


Используйте «ip monitor», чтобы получить изменения состояния ссылки REAL TIME.


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

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


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

ifplugd и netplugd


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

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

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

eth0/carrier

Он показывает 0 или 1


на arch linux. (im не уверен в других дистрибутивах) вы можете просмотреть операционную систему. который отображается, если он подключен или недоступен, если не работает операционная система

/sys/class/net/(interface name here)/operstate
#you can also put watch 
watch -d -n -1 /sys/class/net/(interface name here)/operstate

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

/sys/class/net/

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

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

eth0/carrier:1
eth0/operstate:unknown

Удаленный провод:

eth0/carrier:0
eth0/operstate:down

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

eth0/operstate:up
eth0/carrier:1

Side Trick: убирать все свойства сразу:

grep "" eth0/* 

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


Из подсказки python попробуйте это.

import gtk

icon = gtk.StatusIcon()
icon.set_from_stock(gtk.STOCK_ABOUT)

gtk.main()

Вы должны увидеть значок в системном трее.

См. Этот snippet для большего примера.





linux networking connection detection