Come rilevare lo stato fisico collegato di un cavo / connettore di rete?
-
03-07-2019 - |
Domanda
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:
- Uso di "ifconfig", poiché è possibile collegare un cavo di rete ma la rete non è configurata correttamente o non è attualmente attiva.
- 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.
Suppongo di non poterti mettere entrambi come risposta corretta? Ed è probabilmente giusto per te che io scelga uno. Lanciare una moneta immagino? Ancora grazie!
Soluzione
Vuoi dare un'occhiata ai nodi in
/sys/class/net/
Ho sperimentato il mio:
Cavo collegato:
eth0/carrier:1
eth0/operstate:unknown
Cavo rimosso:
eth0/carrier:0
eth0/operstate:down
Cavo ricollegato:
eth0/carrier:1
eth0/operstate:up
Trucco laterale: raccolta di tutte le proprietà contemporaneamente in modo semplice:
grep "" eth0/*
Questo costituisce un bel elenco di coppie chiave: valore
.
Altri suggerimenti
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
Utilizza 'ip monitor' per ottenere le modifiche allo stato dei collegamenti IN TEMPO REALE.
cat / sys / class / net / ethX
è di gran lunga il metodo più semplice.
L'interfaccia deve essere attiva, altrimenti verrà visualizzato un errore argomento non valido.
Quindi prima:
ifconfig ethX up
Quindi:
cat /sys/class/net/ethX
A basso livello, questi eventi possono essere rilevati usando rtnetlink socket, 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 ad esempio un cavo di rete collegato e disconnesso). Se hai bisogno di qualcosa di più potente, dai un'occhiata al mio linguaggio di programmazione NCD , a linguaggio di programmazione progettato per le configurazioni di rete.
Ad esempio, un semplice script NCD che stamperà " cable in " e "uscita cavo" 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 ()
utilizza rtnetlink e net.backend.waitdevice ()
utilizza 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.
Esistono due demoni che rilevano questi eventi:
ifplugd e netplugd
Le distribuzioni Linux più moderne usano NetworkManager per questo. È possibile utilizzare D-BUS per ascoltare gli eventi.
Se vuoi che uno strumento da riga di comando controlli lo stato, puoi anche usare mii-tool
, dato che hai in mente Ethernet.
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
Alcune precisazioni e trucchi
-
Faccio tutto questo come utente normale (non root )
-
Ottieni informazioni da
dmesg
L'uso di
dmesg
è una delle prime cose da fare per indagare stato corrente 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 -n1
ma preferisco usaresed
.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
-
Prova lo pseudo filesystem
/ sys
Leggere o scrivere in
/ sys
potrebbe danneggiare il sistema, specialmente se eseguito come root ! Sei stato avvisato ;-)Questo è un metodo di pooling, non un vero tracciamento degli eventi .
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
(Premi Invio per uscire dal loop)
Nota: richiede l'installazione di
patch
. -
Bene, deve esserci già qualcosa su questo ...
A seconda dell'installazione Linux , è possibile aggiungere gli script
if-up
eif-down
per poter reagire a questo tipo di eventi .Su basato su Debian (come Ubuntu ), puoi archiviare i tuoi script in
/etc/network/if-down.d /etc/network/if-post-down.d /etc/network/if-pre-up.d /etc/network/if-up.d
vedi
man interfaces
per maggiori informazioni.
tail -f /var/log/syslog | grep -E 'link (up|down)'
o per me più veloce diventa:
tail -f /var/log/syslog | grep 'link \(up\|down\)'
Ascolterà il file syslog.
Risultato (se disconnettersi e riconnettersi dopo 4 secondi):
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
su arch linux. (non sono sicuro su altre distro) è possibile visualizzare l'operstate. che si presenta se connesso o inattivo se non l'opposto vive su
/sys/class/net/(interface name here)/operstate
#you can also put watch
watch -d -n -1 /sys/class/net/(interface name here)/operstate
Puoi puoi usare 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 in / sys / class / net / eth0 / operstate
.
Stavo usando il mio dispositivo potenziato OpenWRT come ripetitore (che aggiunge capacità di 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 non è stato collegato nulla e qualcosa > 0 se qualcosa è stato collegato (anche se è stato collegato e da quando è stato rimosso) dall'ultimo ciclo di accensione o riavvio.
Spero che questo aiuti qualcuno almeno!