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

StackOverflow https://stackoverflow.com/questions/808560

Вопрос

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

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

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

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

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


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

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

Это было полезно?

Решение

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

/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 пары.

Другие советы

Вы можете использовать инструмент 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 это, безусловно, самый простой метод.

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

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

ifconfig ethX up

Тогда:

cat /sys/class/net/ethX

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

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

Например, простой скрипт NCD, который выведет "cable in" и "cable out" в стандартный вывод (при условии, что интерфейс уже запущен):

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 и сетевой подключаемый модуль

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

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

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

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

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

eth0/carrier

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

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

  1. Я делаю все это как обычный пользователь (не корень)

  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это может привести к поломке вашей системы, особенно если работать как корень!Вы были предупреждены ;-)

    Это метод объединения, а не реальный отслеживание событий.

    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 основанный (как Убунту), вы могли бы хранить свои скрипты в

    /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\)'

Он будет прослушивать файл системного журнала.

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

Если запись показывает, что она ЗАПУЩЕНА, значит, интерфейс физически подключен.Это будет показано независимо от того, настроен ли интерфейс.

Это просто еще один способ получить информацию в /sys/class/net/eth0/operstate.

Я использовал свое усовершенствованное устройство OpenWRT в качестве ретранслятора (которое добавляет возможности виртуального ethernet и беспроводной локальной сети) и обнаружил, что значения /sys /class /net / eth0 carrier и opstate были ненадежными.Я поиграл с /sys/ class /net / eth0.1 и / sys / class / net / eth0.2, а также с (по крайней мере, на мой взгляд) отсутствием надежного способа обнаружить, что что-то было физически подключено и разговаривало на любом из портов ethernet.Я нашел немного грубый, но, казалось бы, надежный способ определить, было ли что-либо подключено, по крайней мере, с момента последней перезагрузки / включения питания (что работало именно так, как мне было нужно в моем случае).

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

Вы получите 0, если ничего не было подключено, и что-то > 0, если что-либо было подключено (даже если оно было подключено и с тех пор удалено) с момента последнего цикла включения питания или перезагрузки.

Надеюсь, это хотя бы кому-нибудь поможет!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top