Jak wykryć stan fizycznego podłączenia kabla / złącza sieciowego?

145

W środowisku Linux muszę wykryć stan fizycznego podłączenia lub odłączenia złącza RJ45 do gniazda. Najlepiej używać tylko skryptów BASH.

NIE sprawdzają się w tym celu następujące rozwiązania, które zostały zaproponowane na innych stronach:

  1. Korzystanie z 'ifconfig' - ponieważ kabel sieciowy może być podłączony, ale sieć nie jest poprawnie skonfigurowana lub nie jest aktualnie uruchomiona.
  2. Pinguj hosta - ponieważ produkt będzie znajdować się w sieci LAN przy użyciu nieznanej konfiguracji sieci i nieznanych hostów.

Czy nie ma jakiegoś stanu, którego można użyć w systemie plików / proc (wszystko inne jest tam)?

Jak świat Linuksa ma mieć własną wersję bańki Windows, która wyskakuje z zasobnika ikon, wskazując, że właśnie odłączyłeś kabel sieciowy?


Kent Fredric i Lothar , obie twoje odpowiedzi zaspokajają moją potrzebę ... wielkie dzięki! Którego użyję ... Nadal nie wiem.

Chyba nie mogę was oboje uznać za poprawną odpowiedź? I prawdopodobnie to dla ciebie sprawiedliwe, że wybiorę jedną. Chyba rzucić monetą? Jeszcze raz dzięki!

Jeach
źródło

Odpowiedzi:

228

Chcesz spojrzeć na węzły w programie

/ sys / class / net /

Eksperymentowałem z moim:

Podłączony przewód:

eth0/carrier:1
eth0/operstate:unknown

Usunięto przewód:

eth0/carrier:0
eth0/operstate:down

Przewód ponownie podłączony:

eth0/carrier:1
eth0/operstate:up

Side Trick: zebranie wszystkich dóbr naraz w łatwy sposób:

grep "" eth0/* 

To tworzy ładną listę key:valuepar.

Kent Fredric
źródło
8
Zauważ, że jak mówi Marco poniżej, interfejs musi być włączony (nawet jeśli nie jest skonfigurowany), aby zapytać o te wartości.
Jamie Kitson
11
grep "" eth0 / * jest tak elegancki i łatwy, dzięki! :) Z przełącznikiem -s grep nie będzie narzekał na katalogi.
Ray,
2
Wolę:: grep -H . eth0/*To whipe emty lines i print entry name with należą do każdego wiersza.
F. Hauri
Błędy dotyczące katalogów z grepa można zignorować za pomocą:grep -s "" eth0/*
mrtumnus
Pamiętaj, że interfejs musi być włączony. Zobacz odpowiedź Marco poniżej. W moim systemie, eth0 nie jest ustawione domyślnie, a mój program losowo generuje dla niego adres IP. Otrzymuję błąd „Nieprawidłowy argument” z łapania przewoźnika
VocoJax
84

Możesz użyć 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

Aby uzyskać tylko status łącza, możesz użyć grep:

$ sudo ethtool eth0 | grep Link
    Link detected: yes
lothar
źródło
łącze ip | grep ROZSYŁANIE | cut -d ':' -f 2 | podczas czytania i; zrobić echo $ i; ethtool $ i | grep Link; gotowe
Bryan Hunt
3
Zauważ, że jak mówi Marco poniżej, interfejs musi być włączony (nawet jeśli nie jest skonfigurowany), aby zapytać o te wartości.
Jamie Kitson
to jest niesamowite! Miałem sposób, aby sprawdzić, czy Ethernet jest dostępny, czy Ethernet jest włączony, czy Ethernet jest podłączony, ale nie ma możliwości sprawdzenia, czy rzeczywisty kabel jest podłączony. grep Linkczy to. Dziękuję Ci!!
ᴛʜᴇᴘᴀᴛᴇʟ
Nie działa tutaj. Ubuntu 16.04 na sprzęcie HP. nieskonfigurowane interfejsy są „bez łącza”, nawet jeśli są wymuszone up.
0xF2
26

Użyj „monitora ip”, aby uzyskać zmiany stanu łącza w CZASIE RZECZYWISTYM.

Peter Quiring
źródło
3
W moim przypadku jest to jedyna odpowiedź, która zadziałała ... / sys / class / net / eth0 / carrier wciąż pokazuje, 1kiedy mój kabel jest odłączony, podczas gdy ip monitorfaktycznie coś pokazuje
Tim Tisdall
Można podziękować niektórym szerzej na temat tej metody, Peter. Coś jak każdy przykład, który odpowiada na pierwotne pytanie dotyczące znajomości stanu wtyczki kabla.
Sopalajo de Arrierez
17

cat /sys/class/net/ethX jest zdecydowanie najłatwiejszą metodą.

Interfejs musi być jednak włączony, w przeciwnym razie pojawi się błąd nieprawidłowego argumentu.

Więc najpierw:

ifconfig ethX up

Następnie:

cat /sys/class/net/ethX
Marco
źródło
4
Spróbuj wpisać „cat / sys / class / net / eth [n] / operstate”, gdzie [n] to numer urządzenia eth.
pmont
To tylko mówi ci, czy eth [n] jest włączone. Jeśli jest wyłączone, nie mówi ci, czy kabel jest podłączony, czy nie.
Brice,
@Brice, rzeczywiście, chcesz sprawdzić plik, ethX/carrierktóry ma wartość 1, jeśli zostanie wykryty 'nośnik', co oznacza, że ​​kabel jest podłączony i przenosi dane ...
Alexis Wilke
Pomogło mi to przy użyciu poleceń Process Runtime Exec, aby sprawdzić, czy kabel jest podłączony w systemie Android.
Arlyn
Lub po ifconfig ethX up, ifconfig ethX i poszukaj RUNNING.
craig65535,
8

Na niskim poziomie zdarzenia te można przechwytywać za pomocą gniazd rtnetlink , bez żadnego odpytywania. Uwaga dodatkowa: jeśli używasz rtnetlink, musisz współpracować z udev, w przeciwnym razie twój program może się pomylić, gdy udev zmieni nazwę nowego interfejsu sieciowego.

Problem z konfiguracją sieci za pomocą skryptów powłoki polega na tym, że skrypty powłoki są straszne przy obsłudze zdarzeń (takich jak podłączanie i odłączanie kabla sieciowego). Jeśli potrzebujesz czegoś mocniejszego, spójrz na mój język programowania NCD, język programowania przeznaczony do konfiguracji sieciowych.

Na przykład prosty skrypt NCD, który wypisze „cable in” i „cable out” na stdout (zakładając, że interfejs jest już włączony):

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 :)
}

(wewnętrznie net.backend.waitlink()używa rtnetlink i net.backend.waitdevice()używa udev)

Ideą NCD jest to, że używasz go wyłącznie do konfigurowania sieci, więc zwykle polecenia konfiguracyjne pojawiałyby się pomiędzy, takimi jak:

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");
}

Ważną częścią, na którą należy zwrócić uwagę, jest to, że wykonanie może się cofnąć ; w drugim przykładzie, na przykład, jeśli kabel zostanie wyciągnięty, adres IP zostanie automatycznie usunięty.

Ambroz Bizjak
źródło
4

Istnieją dwa demony, które wykrywają te zdarzenia:

ifplugd i netplugd

Niemiecki
źródło
Używam ifplugstatusnarzędzia z ifplugddemona. Nie potrzebujesz argumentów, po prostu wpisz, ifplugstatusa otrzymasz całą kartę sieciową jako podłączoną lub odłączoną.
Sopalajo de Arrierez
3

Większość nowoczesnych dystrybucji Linuksa używa do tego NetworkManagera . Możesz użyć D-BUS do nasłuchiwania wydarzeń.

Jeśli chcesz, aby narzędzie wiersza poleceń sprawdzało stan, możesz również użyć mii-tool, biorąc pod uwagę, że masz na myśli Ethernet.

andri
źródło
3
mii-tool zostało zastąpione przez ethtool. mii-tool nie wie o połączeniach GigE.
JimB
ponadto większość serwerów ma ręcznie skonfigurowane adaptery, które są ignorowane przez NM.
JimB
1
mii-toolwydaje się być jedynym poleceniem, które może raportować stan łącza, gdy interfejs jest wyłączony.
powodzenia
2

Używam tego polecenia, aby sprawdzić, czy przewód jest podłączony:

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

Jeśli wynik będzie w górę lub w dół. Czasami pokazuje nieznane, wtedy musisz sprawdzić

eth0/carrier

Pokazuje 0 lub 1

Sarvar Nishonboev
źródło
2

Trochę precyzji i sztuczek

  1. Robię to wszystko jako zwykły użytkownik (nie root )

  2. Pobierz informacje z dmesg

    Użycie dmesgjest jedną z pierwszych rzeczy do zrobienia w celu sprawdzenia aktualnego stanu systemu:

    dmesg | sed '/eth.*Link is/h;${x;p};d'
    

    mógłby odpowiedzieć na przykład:

    [936536.904154] e1000e: eth0 NIC Link is Down
    

    lub

    [936555.596870] e1000e: eth0 NIC Link is Up 100 Mbps Full Duplex, Flow Control: Rx/Tx
    

    w zależności od stanu, komunikat może się różnić w zależności od używanego sprzętu i sterowników.

    Uwaga: można to napisać, dmesg|grep eth.*Link.is|tail -n1ale wolę używać 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. Przetestuj /syspseudosystemy plików

    Czytanie lub pisanie poniżej /sysmoże zepsuć twój system, zwłaszcza jeśli działa jako root ! Zostałeś ostrzeżony ;-)

    To jest metoda łączenia, a nie rzeczywiste śledzenie zdarzeń .

    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
    

    Może wyrenderować coś takiego (po odłączeniu i ponownym podłączeniu, w zależności od):

    +++ -   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
    

    (Naciśnij, Enteraby wyjść z pętli)

    Uwaga: to wymaga patchzainstalowania.

  4. W porządku, musi już być coś w tym ...

    W zależności od instalacji Linuksa możesz dodać if-upi if-downskrypty, aby móc reagować na tego typu zdarzenia.

    W systemie Debian (takim jak Ubuntu ) możesz przechowywać swoje skrypty w

    /etc/network/if-down.d
    /etc/network/if-post-down.d
    /etc/network/if-pre-up.d
    /etc/network/if-up.d
    

    zobacz man interfaceswięcej informacji.

F. Hauri
źródło
Dziękuję za uwagi i wkład w tej sprawie. Chociaż zdajesz sobie sprawę, że są to „automatyczne” skrypty. W punkcie 2, kiedy mówisz wyjście ' lub ' inne wyjście, albo kiedy mówisz "w zależności od stanu, komunikat może się różnić w zależności od używanego sprzętu i sterowników " ... to jest naprawdę duży problem. Dane wyjściowe muszą być spójne lub skrypty produkcyjne zaczynają się zepsuć. Ale mimo wszystko to dobra informacja, dziękuję.
Jeach
@Jeach Wyjście może się różnić, co oznacza: Możesz użyć innego sterownika niż,e1000 a wieczór może nastąpić w innym czasie niż936555.596870 , ale zawsze zobaczysz NIC Link is.
F. Hauri
2

Państwo może używać ifconfig.

# ifconfig eth0 up
# ifconfig eth0

Jeśli wpis pokazuje RUNNING, interfejs jest fizycznie podłączony. Będzie to widoczne niezależnie od tego, czy interfejs jest skonfigurowany.

To tylko kolejny sposób na uzyskanie informacji /sys/class/net/eth0/operstate.

craig65535
źródło
Zaoszczędziłeś mi godziny !!
ADITYA VALLURU
1

na arch Linux. (nie jestem pewien w innych dystrybucjach) możesz wyświetlić operstate. który pojawia się, jeśli jest podłączony lub wyłączony, jeśli nie, operstate żyje

/sys/class/net/(interface name here)/operstate
#you can also put watch 
watch -d -n -1 /sys/class/net/(interface name here)/operstate
Skrmnghrd
źródło
1
tail -f /var/log/syslog | grep -E 'link (up|down)'

lub dla mnie szybciej dostaje:

tail -f /var/log/syslog | grep 'link \(up\|down\)'

Będzie nasłuchiwać pliku syslog.

Wynik (w przypadku rozłączenia i ponownego podłączenia po 4 sekundach):

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
Dima
źródło
1

Jakoś, jeśli chcesz sprawdzić, czy kabel Ethernet jest podłączony do linuxa po poleceniu: "ifconfig eth0 down". Znajduję rozwiązanie: użyj narzędzia 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

jeśli kabel jest podłączony, test łącza wynosi 0, w przeciwnym razie 1.

kyzrong
źródło
0

Używałem mojego ulepszonego urządzenia OpenWRT jako repeatera (który dodaje możliwości wirtualnej sieci Ethernet i bezprzewodowej sieci LAN) i stwierdziłem, że wartości nośnika i opstate / sys / class / net / eth0 były niewiarygodne. Bawiłem się /sys/class/net/eth0.1 i /sys/class/net/eth0.2 z (przynajmniej według moich ustaleń) żadnym niezawodnym sposobem wykrycia, że ​​coś jest fizycznie podłączone i rozmawia portów Ethernet. Wymyśliłem nieco prymitywny, ale pozornie niezawodny sposób na wykrycie, czy coś zostało podłączone przynajmniej od ostatniego restartu / stanu zasilania (co działało dokładnie tak, jak tego potrzebowałem w moim przypadku).

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

Otrzymasz 0, jeśli nic nie zostało podłączone i coś> 0, jeśli coś zostało podłączone (nawet jeśli zostało podłączone i od tego czasu usunięte) od ostatniego włączenia lub ponownego uruchomienia.

Mam nadzieję, że to przynajmniej komuś pomoże!

JxAxMxIxN
źródło