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


145

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

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

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

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

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


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

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

Ответы:


228

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

/ SYS / класс / сеть /

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

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

eth0/carrier:1
eth0/operstate:unknown

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

eth0/carrier:0
eth0/operstate:down

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

eth0/carrier:1
eth0/operstate:up

Side Trick: легко собрать все свойства сразу:

grep "" eth0/* 

Это формирует хороший список key:valueпар.


8
Обратите внимание, что, как говорит Марко ниже, интерфейс должен быть включен (даже если не настроен) для запроса этих значений.
— Джейми Китсон

11
grep "" eth0 / * так элегантно и просто, спасибо! :) С ключом -s grep не будет жаловаться на каталоги.
— Рэй

2
Я предпочитаю:: grep -H . eth0/*это отбрасывать пустые строки и печатать название записи с каждой строки.
— Ф. Хаури

Ошибки о каталогах из grep можно игнорировать с помощью:grep -s "" eth0/*
— mrtumnus

Обратите внимание, что интерфейс должен быть включен. Смотрите ответ Марко ниже. В моей системе eth0 не установлен по умолчанию, и моя программа случайным образом генерирует для него IP-адрес. Я получаю сообщение об ошибке «Недопустимый аргумент» от присмотра за носителем
— VocoJax

84

Вы можете использовать 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-ссылка | grep BROADCAST | cut -d ':' -f 2 | пока читаю я; сделать эхо $ я; ethtool $ i | grep Link; сделано
— Брайан Хант

3
Обратите внимание, что, как говорит Марко ниже, интерфейс должен быть включен (даже если не настроен) для запроса этих значений.
— Джейми Китсон

это круто! У меня был способ проверить, доступен ли Ethernet, включен ли Ethernet, подключен ли Ethernet, но нет способа проверить, был ли подключен реальный кабель. grep LinkЯвляется ли. Спасибо!!
— ᴛʜᴇᴘᴀᴛᴇʟ

Не работает здесь Ubuntu 16.04 на оборудовании HP. ненастроенные интерфейсы являются «без связи», даже когда вынуждены upзаявить.
— 0xF2

26

Используйте «IP-монитор», чтобы получить изменения состояния связи в реальном времени.


3
В моем случае это единственный ответ, который сработал ... / sys / class / net / eth0 / carrier по-прежнему показывает, 1когда мой кабель отключен, хотя на ip monitorсамом деле что-то показывает
— Тим Тисдалл

Можно поблагодарить Питера за расширение этого метода. Примерно как любой пример, который отвечает на оригинальный вопрос о знании состояния штекера кабеля.
— Сопалайо де Арриерес

17

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

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

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

ifconfig ethX up

Затем:

cat /sys/class/net/ethX

4
Попробуйте "cat / sys / class / net / eth [n] / operstate", где [n] - номер устройства eth.
— pmont

Это только говорит вам, если eth [n] вверх, если он не работает, он не говорит вам, если кабель подключен или нет.
— Брайс

@Brice, действительно, вы хотите проверить файл, ethX/carrierкоторый равен 1, если обнаружен «носитель», что означает, что кабель подключен и передает данные ...
— Алексис Уилке

Это сработало для меня с помощью команд Process Runtime Exec, чтобы проверить, подключен ли кабель в Android.
— Арлин

Или, если ifconfig ethX up, ifconfig ethX и искать RUNNING.
— craig65535

8

На низком уровне эти события могут быть перехвачены с помощью 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

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

ifplugd и netplugd


Я использую ifplugstatusинструмент от ifplugdдемона. Нет необходимости в аргументах, просто введите, ifplugstatusи вы получите все NIC как подключенные или отключенные.
— Сопалахо де Арриерес

3

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

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


3
mii-tool был заменен ethtool. mii-tool не знает о ссылках GigE.
— ДжимБ

Кроме того, большинство серверов имеют настроенные вручную адаптеры, которые игнорируются NM.
— ДжимБ

1
mii-toolкажется, единственная команда, которая может сообщать о состоянии связи, когда интерфейс не работает.
— успешно,

2

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

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

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

eth0/carrier

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


2

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

  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
    

    (Нажмите, 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больше информации.


Спасибо за ваши комментарии и вклад по этому вопросу. Хотя вы понимаете, что это «автоматизированные» сценарии. В пункте 2, когда вы говорите «вывод» или «другой вывод», или когда вы говорите «в зависимости от состояния, сообщение может меняться в зависимости от используемого оборудования и драйверов » ... это действительно большая проблема. Вывод должен быть согласованным, иначе производственные скрипты начинают ломаться. Но это хорошая информация, спасибо.
— Jeach

Выходные данные @Jeach могут варьироваться в зависимости от: Вы можете использовать другой драйвер,e1000 а вечер может произойти в другое время936555.596870 , но вы все равно увидите NIC Link is.
— Ф. Хаури

2

Вы можете использовать ifconfig.

# ifconfig eth0 up
# ifconfig eth0

Если в записи отображается RUNNING, интерфейс физически подключен. Это будет показано независимо от того, настроен ли интерфейс.

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


Вы сэкономили мои часы!
— ADITYA VALLURU

1

на арке линукс. (Я не уверен, что на других дистрибутивах) вы можете посмотреть на operstate. который появляется, если подключен или вниз, если не находится в штате

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

1
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

1

Так или иначе, если вы хотите проверить, подключен ли Ethernet-кабель к Linux после коммэнда: «ifconfig eth0 down». Я нахожу решение: используйте инструмент 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.


0

Я использовал свое усовершенствованное устройство OpenWRT в качестве повторителя (который добавляет возможности виртуальной сети Ethernet и беспроводной локальной сети) и обнаружил, что значения несущей / opstate / sys / class / net / eth0 были ненадежными. Я поиграл с /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, если что-то было подключено (даже если оно было подключено и с тех пор удалено) с момента последнего включения или перезагрузки.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.