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:

  1. Uso di "ifconfig", poiché è possibile collegare un cavo di rete 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.

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

È stato utile?

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

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

  2. 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 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 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 .

  4. Bene, deve esserci già qualcosa su questo ...

    A seconda dell'installazione Linux , è possibile aggiungere gli script if-up e if-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!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top