Come rilevare lo stato fisico collegato di un cavo / connettore di rete?


145

In un ambiente Linux, devo rilevare lo stato fisico connesso o disconnesso di un connettore RJ45 nella sua presa. Preferibilmente usando solo script BASH.

Le seguenti soluzioni che sono state proposte su altri siti NON funzionano a questo scopo:

  1. Usando 'ifconfig' - poiché un cavo di rete può essere collegato ma la rete non è configurata correttamente o non è attualmente attiva.
  2. Effettua il ping di un host: poiché il prodotto sarà all'interno di una LAN utilizzando una configurazione di rete sconosciuta e host sconosciuti.

Non c'è qualche stato che può essere usato nel file system / proc (tutto il resto è lì)?

In che modo il mondo Linux suppone di avere la propria versione della bolla di Windows che si apre dalla barra delle icone indicando che hai appena scollegato il cavo di rete?


Kent Fredric e lothar , entrambe le tue risposte soddisfano il mio bisogno ... grazie mille! Quale userò ... ancora non lo so.

Immagino di non poterti mettere entrambi come risposta corretta? Ed è probabilmente giusto per te che io scelga uno. Lanciare una moneta immagino? Grazie ancora!

Risposte:


228

Vuoi dare un'occhiata ai nodi in

/ Sys / class / / net

Ho sperimentato il mio:

Cavo collegato:

eth0/carrier:1
eth0/operstate:unknown

Filo rimosso:

eth0/carrier:0
eth0/operstate:down

Cavo ricollegato:

eth0/carrier:1
eth0/operstate:up

Trucco laterale: raccogliere tutte le proprietà contemporaneamente in modo semplice:

grep "" eth0/* 

Questo costituisce un bel elenco di key:valuecoppie.


8
Si noti che come dice Marco sotto l'interfaccia deve essere attiva (anche se non configurata) per interrogare questi valori.
Jamie Kitson,

11
grep "" eth0 / * è così elegante e semplice, grazie! :) Con l'opzione -s grep non si lamenterà delle directory.
Ray

2
Preferisco:: grep -H . eth0/*questo whipe emty lines e stampa il nome della voce appartengono a ciascuna riga.
F. Hauri,

Gli errori relativi alle directory di grep possono essere ignorati con:grep -s "" eth0/*
mrtumnus,

Si noti che l'interfaccia deve essere attiva. Vedi la risposta di Marco sotto. Nel mio sistema, eth0 non è impostato di default e il mio programma genera casualmente un indirizzo IP per esso. Ottengo un errore "Argomento non valido" dal catturare il corriere
VocoJax,

84

Puoi usare 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

Per ottenere solo lo stato del Link puoi usare grep:

$ sudo ethtool eth0 | grep Link
    Link detected: yes

collegamento ip | grep BROADCAST | cut -d ':' -f 2 | mentre leggi i; fare l'eco $ i; ethtool $ i | collegamento grep; fatto
Bryan Hunt il

3
Si noti che come dice Marco sotto l'interfaccia deve essere attiva (anche se non configurata) per interrogare questi valori.
Jamie Kitson,

Questo e spettacolare! ho avuto un modo per verificare se Ethernet è disponibile, se Ethernet è abilitato, se Ethernet è collegato, ma nessun modo per verificare se il cavo effettivo era collegato. grep Linklo fa. Grazie!!
ᴛʜᴇᴘᴀᴛᴇʟ

Non funziona qui. Ubuntu 16.04 su hardware HP. le interfacce non configurate sono "nessun collegamento", anche se costrette a updichiarare.
0xF2,

26

Utilizzare 'ip monitor' per ottenere modifiche allo stato dei collegamenti IN TEMPO REALE.


3
Nel mio caso, questa è l'unica risposta che ha funzionato ... / sys / class / net / eth0 / carrier mostra ancora 1quando il mio cavo è disconnesso mentre ip monitormostra effettivamente qualcosa
Tim Tisdall

Un po 'di espansione su questo metodo potrebbe essere ringraziato, Peter. Qualcosa come qualsiasi esempio che risponda alla domanda originale sulla conoscenza dello stato della spina del cavo.
Sopalajo de Arrierez,

17

cat /sys/class/net/ethX è di gran lunga il metodo più semplice.

L'interfaccia deve essere attiva, altrimenti si otterrà un errore argomento non valido.

Quindi prima di tutto:

ifconfig ethX up

Poi:

cat /sys/class/net/ethX

4
Prova "cat / sys / class / net / eth [n] / operstate" dove [n] è il numero del dispositivo eth.
pmont,

Questo ti dice solo se eth [n] è attivo, se è inattivo non ti dice se il cavo è collegato o meno.
Brice,

@Brice, infatti, vuoi controllare il file ethX/carrierche è 1 se viene rilevato il "corriere", il che significa che un cavo è collegato e trasporta dati ...
Alexis Wilke,

Questo ha funzionato per me usando i comandi di Process Runtime Exec per verificare se il cavo è collegato in Android.
Arlyn,

Oppure, dopo ifconfig ethX, ifconfig ethX e cercare RUNNING.
craig65535,

8

A basso livello, questi eventi possono essere rilevati utilizzando socket rtnetlink , senza alcun polling. Nota a margine: se usi rtnetlink, devi collaborare con udev, altrimenti il ​​tuo programma potrebbe confondersi quando udev rinomina una nuova interfaccia di rete.

Il problema con le configurazioni di rete con script di shell è che gli script di shell sono terribili per la gestione degli eventi (come un cavo di rete che viene inserito e disconnesso). Se hai bisogno di qualcosa di più potente, dai un'occhiata al mio linguaggio di programmazione NCD , un linguaggio di programmazione progettato per le configurazioni di rete.

Ad esempio, un semplice script NCD che stamperà "cable in" e "cable out" su stdout (supponendo che l'interfaccia sia già attiva):

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

(internamente, net.backend.waitlink()usa rtnetlink e net.backend.waitdevice()usa udev)

L'idea di NCD è che lo usi esclusivamente per configurare la rete, quindi normalmente si frapporrevano comandi di configurazione, come:

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

La parte importante da notare è che l'esecuzione può regredire ; nel secondo esempio, ad esempio, se il cavo viene estratto, l'indirizzo IP verrà automaticamente rimosso.


4

Esistono due demoni che rilevano questi eventi:

ifplugd e netplugd


Uso lo ifplugstatusstrumento dal ifplugddemone. Non c'è bisogno di argomenti, basta digitare ifplugstatuse otterrai tutta la scheda NIC come collegata o scollegata.
Sopalajo de Arrierez,

3

La maggior parte delle moderne distribuzioni Linux usano NetworkManager per questo. È possibile utilizzare D-BUS per ascoltare gli eventi.

Se si desidera che uno strumento da riga di comando verifichi lo stato, è possibile utilizzare anche mii-tool, poiché si ha in mente Ethernet.


3
mii-tool è stato sostituito da ethtool. mii-tool non è a conoscenza dei collegamenti GigE.
JimB,

inoltre, la maggior parte dei server ha adattatori configurati manualmente, che sono ignorati da NM.
JimB,

1
mii-toolsembra essere l'unico comando in grado di segnalare lo stato del collegamento quando l'interfaccia non è attiva.
donothings successo

2

Uso questo comando per verificare che un filo sia collegato:

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

Se il risultato sarà su o giù. A volte mostra sconosciuto, quindi è necessario controllare

eth0/carrier

Mostra 0 o 1


2

Alcune precisazioni e trucchi

  1. Faccio tutto questo come utente normale (non root )

  2. Ottieni informazioni da dmesg

    utilizzando dmesg è una delle prime cose da fare per verificare lo stato attuale del sistema:

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

    potrebbe rispondere a qualcosa del tipo:

    [936536.904154] e1000e: eth0 NIC Link is Down
    

    o

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

    a seconda dello stato, il messaggio può variare a seconda dell'hardware e dei driver utilizzati.

    Nota: questo potrebbe essere scritto dmesg|grep eth.*Link.is|tail -n1ma preferisco usare 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. Prova in giro /sys pseudo filesystem

    Leggere o scrivere sotto /syspotrebbe danneggiare il sistema, specialmente se eseguito come root ! Sei stato avvisato ;-)

    Questo è un metodo di pooling, non un rilevamento di eventi reali .

    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
    

    Potrebbe eseguire il rendering di qualcosa di simile (una volta scollegato e ricollegato, a seconda):

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

    (Colpire Enter per uscire dal loop)

    Nota: questo richiede patch l'installazione.

  4. Bene, ci deve essere già qualcosa in questo ...

    A seconda dell'installazione di Linux , è possibile aggiungere if-upeif-down script per poter reagire a questo tipo di eventi.

    Su Debian (come Ubuntu ), puoi archiviare i tuoi script

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

    vedere man interfacesper maggiori informazioni.


Grazie per i vostri commenti e input in merito. Tuttavia, ti rendi conto che si tratta di script "automatizzati". Al punto 2, quando dici " o " un altro output, o quando dici "a seconda dello stato, il messaggio può variare a seconda dell'hardware e dei driver utilizzati " ... questo è un grosso problema. L'output deve essere coerente o gli script di produzione iniziano a non funzionare. Ma sono buone informazioni a prescindere, grazie.
Jeach,

L'output di @Jeach può variare in base alla media: è possibile utilizzare un driver diverso da quelloe1000 e l' eventment potrebbe verificarsi in un altro momento rispetto a936555.596870 , ma vedrai sempre NIC Link is.
F. Hauri,

2

È possibile utilizzare ifconfig.

# ifconfig eth0 up
# ifconfig eth0

Se la voce mostra RUNNING, l'interfaccia è fisicamente connessa. Questo verrà mostrato indipendentemente dal fatto che l'interfaccia sia configurata.

Questo è solo un altro modo per ottenere le informazioni /sys/class/net/eth0/operstate.


Mi hai salvato le ore !!
ADITYA VALLURU

1

su arch linux. (non sono sicuro su altre distro) è possibile visualizzare l'operstate. che si presenta se connesso o inattivo se non l'opposto sopravvive

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

o per me più veloce ottiene:

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

Ascolterà il file syslog.

Risultato (se disconnetti e dopo 4 secondi riconnetti):

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

In qualche modo, se si desidera verificare se il cavo Ethernet è stato collegato a Linux dopo la lode: "ifconfig eth0 down". Trovo una soluzione: utilizzare lo strumento 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

se il cavo è collegato, il test di collegamento è 0, altrimenti è 1.


0

Stavo usando il mio dispositivo potenziato OpenWRT come ripetitore (che aggiunge funzionalità ethernet virtuale e wireless lan) e ho scoperto che i valori di carrier e opstate / sys / class / net / eth0 erano inaffidabili. Ho giocato con /sys/class/net/eth0.1 e /sys/class/net/eth0.2 e (almeno per quanto mi è stato riscontrato) nessun modo affidabile per rilevare che qualcosa era fisicamente collegato e parlare su qualsiasi delle porte Ethernet. Ho trovato un modo un po 'grezzo ma apparentemente affidabile per rilevare se qualcosa era stato collegato almeno dall'ultimo stato di riavvio / accensione (che ha funzionato esattamente come avevo bisogno nel mio caso).

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

Otterrai uno 0 se nulla è stato collegato e qualcosa> 0 se qualcosa è stato collegato (anche se è stato collegato e da quando rimosso) dall'ultimo ciclo di accensione o riavvio.

Spero che questo aiuti qualcuno almeno!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.