Як виявити фізичний стан підключення мережевого кабелю / роз'єму?


145

У середовищі Linux мені потрібно виявити фізичний підключений або відключений стан роз'єму RJ45 до його розетки. Переважно використовувати тільки сценарії BASH.

Наступні рішення, запропоновані на інших сайтах, НЕ працюють для цього:

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

Чи не існує якогось стану, який можна використовувати у файловій системі / proc (все інше є там)?

Як, можливо, у світі Linux є своя версія міхура Windows, що вискакує з лотка значків, що вказує на те, що ви щойно відключили мережевий кабель?


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

Гадаю, я не можу поставити вас обох як правильну відповідь? І я, мабуть, справедливо для вас, що я вибираю один. Переверніть монету, напевно? Ще раз дякую!

Відповіді:


228

Ви хочете подивитися вузли в

/ sys / клас / нетто /

Я експериментував зі своїм:

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

eth0/carrier:1
eth0/operstate:unknown

Дріт вилучено:

eth0/carrier:0
eth0/operstate:down

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

eth0/carrier:1
eth0/operstate:up

Бічний трюк: збирання всіх властивостей відразу простий спосіб:

grep "" eth0/* 

Це формує приємний список key:valueпар.


8
Зауважте, що, як каже Марко, інтерфейс повинен бути вгору (навіть якщо він не налаштований) для запиту цих значень.
— Джеймі Кітсон

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

2
Я віддаю перевагу:: grep -H . eth0/*Цей вістрявий рядок та надрукована назва запису з належать кожному рядку.
— Ф. Хаурі

Помилки щодо каталогів від grep можна ігнорувати за допомогою:grep -s "" eth0/*
— mrtumnus

Зауважте, що інтерфейс повинен бути налаштований. Відповідь Марко дивіться нижче. У моїй системі eth0 не встановлено за замовчуванням, і моя програма випадково генерує IP-адресу для неї. Я отримую помилку "Недійсний аргумент" від
— котирування

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 | вирізати -d ':' -f 2 | під час читання i; робити відлуння $ i; ettool $ i | grep Посилання; виконано
— Брайан Хант

3
Зауважте, що, як каже Марко, інтерфейс повинен бути вгору (навіть якщо він не налаштований) для запиту цих значень.
— Джеймі Кітсон

Це круто! У мене був спосіб перевірити, чи доступна ethernet, чи включена ethernet, чи підключена Ethernet, але немає можливості перевірити, чи був підключений власне кабель. grep Linkробить це. Дякую!!
— ᴛʜᴇᴘᴀᴛᴇʟ

Тут не працює. Ubuntu 16.04 на апараті HP. неконфігуровані інтерфейси "не мають зв'язку", навіть коли вони змушені upконстатувати.
— 0xF2

26

Використовуйте 'ip monitor', щоб отримати зміни стану справжнього часу зв'язку.


3
У моєму випадку це єдина відповідь, яка спрацювала ... / sys / class / net / eth0 / carrier все ще показує, 1коли мій кабель відключений, а ip monitorнасправді щось показує
— Тім Тісдалл

Деякі розширення цього методу можна подякувати, Пітер. Щось на зразок будь-якого прикладу, який відповідає на початкове запитання про стан відомостей про кабель.
— Sopalajo de Arrierez

17

cat /sys/class/net/ethX на сьогоднішній день найпростіший метод.

Хоча інтерфейс має бути налаштований, інакше ви отримаєте помилкову помилку аргументу.

Тож спочатку:

ifconfig ethX up

Тоді:

cat /sys/class/net/ethX

4
Спробуйте "cat / sys / class / net / eth [n] / operstate", де [n] - номер пристрою eth.
— пмонт

Це повідомляє лише про те, що значення eth [n] увімкнено, якщо воно вниз, воно не повідомляє вам, підключений чи ні кабель.
— Бріс

@Brice, дійсно, ви хочете перевірити файл, ethX/carrierякий є 1, якщо виявлено "оператор", це означає, що кабель підключений і несуть дані ...
— Alexis Wilke

Для мене це працювало за допомогою команд Process Runtime Exec, щоб перевірити, чи кабель підключений в Android.
— Арлін

Або, якщо ifconfig ethX вгору, ifconfig ethX і шукайте РЕЧЕННЯ.
— craig65535

8

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

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

Наприклад, простий скрипт NCD, який буде друкувати "кабель в" і "вивести кабель" в stdout (якщо припустимо, що інтерфейс вже налаштований):

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-інструмент витіснив ettool. mii-tool не знає посилань GigE.
— JimB

крім того, більшість серверів налаштовує вручну адаптери, які ігноруються NM.
— JimB

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

на аркуші Linux. (я не впевнений, що в інших дистрибутивах) ви можете переглянути стан. який відображається, якщо він підключений чи вниз, якщо не працює оперстат

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

Він прослухає файл syslog.

Результат (якщо від'єднатися та через 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 та бездротової мережі) і виявив, що значення / 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.