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


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.