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


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.