web-dev-qa-db-fra.com

Comment détecter l'état de connexion physique d'un câble/connecteur réseau?

Dans un environnement Linux, je dois détecter l’état physique connecté ou déconnecté d’un connecteur RJ45 sur son support. Utilisez de préférence uniquement les scripts BASH.

Les solutions suivantes proposées sur d'autres sites NE fonctionnent PAS à cette fin:

  1. Utilisation de 'ifconfig' - car un câble de réseau peut être connecté mais le réseau n'est pas configuré correctement ou n'est pas actuellement opérationnel.
  2. Envoyez une commande ping à un hôte - car le produit se trouvera dans un réseau local utilisant une configuration réseau inconnue et des hôtes inconnus.

N'y a-t-il pas un état qui peut être utilisé dans le système de fichiers/proc (tout le reste est dedans)?

Comment le monde Linux est-il supposé avoir sa propre version de la bulle Windows qui apparaît dans la barre d'état indiquant que vous venez de débrancher le câble réseau?


Kent Fredric et lothar, vos deux réponses répondent à mon besoin ... merci beaucoup! Lequel je vais utiliser ... Je ne sais toujours pas.

Je suppose que je ne peux pas vous dire tous les deux que c'est la bonne réponse? Et c'est probablement juste pour vous que j'en choisisse un. Lancer une pièce je suppose? Merci encore!

125
Jeach

Vous voulez regarder les nœuds dans 

/sys/class/net /

J'ai expérimenté avec le mien: 

Fil branché: 

eth0/carrier:1
eth0/operstate:unknown

Fil enlevé: 

eth0/carrier:0
eth0/operstate:down

Fil branché à nouveau:

eth0/carrier:1
eth0/operstate:up

Side Trick: récolter toutes les propriétés à la fois facilement: 

grep "" eth0/* 

Ceci forme une liste de Nice de key:value paires. 

198
Kent Fredric

Vous pouvez utiliser 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

Pour obtenir uniquement le statut du lien, vous pouvez utiliser grep:

$ Sudo ethtool eth0 | grep Link
    Link detected: yes
77
lothar

Utilisez 'ip monitor' pour obtenir les changements d’état des liens en temps réel.

24
Peter Quiring

cat /sys/class/net/ethX est de loin la méthode la plus simple.

Cependant, l'interface doit être active, sinon vous obtiendrez une erreur d'argument invalide.

Alors d'abord:

ifconfig ethX up

Ensuite:

cat /sys/class/net/ethX
15
Marco

Au niveau bas, ces événements peuvent être interceptés à l’aide de rtnetlink sockets, sans interrogation. Remarque secondaire: si vous utilisez rtnetlink, vous devez travailler avec udev. Sinon, votre programme risque d’être perturbé lorsque udev renomme une nouvelle interface réseau.

Le problème avec les configurations réseau à l'aide de scripts Shell est que les scripts Shell sont terribles pour la gestion des événements (par exemple, un câble réseau branché et connecté). Si vous avez besoin de quelque chose de plus puissant, jetez un coup d’œil à mon langage de programmation NCD , un langage de programmation conçu pour les configurations réseau.

Par exemple, un simple script NCD qui imprimera les entrées "cable in" et "cable out" sur stdout (en supposant que l'interface est déjà active):

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

(en interne, net.backend.waitlink() utilise rtnetlink et net.backend.waitdevice() utilise udev)

L'idée de NCD est que vous l'utilisez exclusivement pour configurer le réseau. Normalement, les commandes de configuration s'interposent, telles que:

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 partie importante à noter est que l'exécution est autorisée à régresser; dans le deuxième exemple, par exemple, si le câble est débranché, l'adresse IP sera automatiquement supprimée.

8
Ambroz Bizjak

Il existe deux démons qui détectent ces événements:

ifplugd et netplugd

4
germanjaber

J'utilise cette commande pour vérifier qu'un fil est connecté:

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

Si le résultat sera haut ou bas. Parfois, il montre inconnu, alors vous devez vérifier 

eth0/carrier

Il montre 0 ou 1

2
Sarvar Nishonboev

Quelques précisions et astuces

  1. Je fais tout cela comme utilisateur normal (pas root )

  2. Récupère les informations de dmesg

    Utiliser dmesg est l’une des premières choses à faire pour demander état actuel du système:

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

    pourrait répondre à quelque chose comme:

    [936536.904154] e1000e: eth0 NIC Link is Down
    

    ou

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

    selon l'état, le message peut varier en fonction du matériel et des pilotes utilisés.

    Nota: cela pourrait être écrit dmesg|grep eth.*Link.is|tail -n1 mais je préfère utiliser 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. Testez autour du pseudo système de fichiers /sys

    Lire ou écrire sous /sys peut casser votre système, surtout s’il est exécuté en tant que root ! Tu as été prévenu ;-)

    Il s’agit d’une méthode de mise en commun et non d’un véritable suivi d’événements .

    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
    

    Pourrait rendre quelque chose comme (une fois que vous avez débranché et rebranché, selon):

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

    (Frappé Enter sortir de la boucle)

    Note: Ceci nécessite que patch soit installé.

  4. Enfin, il doit déjà y avoir quelque chose à ce sujet ...

    Selon Installation de Linux , vous pouvez ajouter des scripts if-up et if-down pour pouvoir réagir à ce type d’événements.

    Sur Debian (comme Ubuntu ), vous pouvez stocker vos scripts dans

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

    voir man interfaces pour plus d'informations.

2
F. Hauri

La plupart des distributions Linux modernes utilisent NetworkManager pour cela. Vous pouvez utiliser D-BUS pour écouter les événements.

Si vous souhaitez qu'un outil de ligne de commande vérifie l'état, vous pouvez également utiliser mii-tool, dans la mesure où vous avez Ethernet à l'esprit.

2
andri

sur Arch Linux. (Je ne suis pas sûr sur les autres distributions), vous pouvez voir le poste. qui apparaît si connecté ou en panne sinon l'operstate vit sur 

/sys/class/net/(interface name here)/operstate
#you can also put watch 
watch -d -n -1 /sys/class/net/(interface name here)/operstate
0
screaminghard

Vous pouvez utiliser ifconfig.

# ifconfig eth0 up
# ifconfig eth0

Si l'entrée indique RUNNING, l'interface est physiquement connectée. Cela sera affiché indépendamment du fait que l'interface soit configurée.

C'est juste un autre moyen d'obtenir l'information dans /sys/class/net/eth0/operstate.

0
craig65535
tail -f /var/log/syslog | grep -E 'link (up|down)'

ou pour moi plus vite obtient:

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

Il écoutera le fichier syslog.

Résultat (si déconnecté et reconnecté après 4 secondes):

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
0
Dima

J'utilisais mon périphérique amélioré OpenWRT en tant que répéteur (ce qui ajoute des capacités Ethernet et LAN sans fil virtuelles) et j'ai constaté que les valeurs d'opérateur/sys/class/net/eth0 n'étaient pas fiables. J'ai également joué avec /sys/class/net/eth0.1 et /sys/class/net/eth0.2 avec (du moins à ma conclusion) aucun moyen fiable de détecter que quelque chose a été physiquement branché et de parler des ports Ethernet. J'ai trouvé un moyen un peu brutal mais apparemment fiable de détecter si quelque chose avait été branché depuis le dernier état de redémarrage/poweron au moins (ce qui a fonctionné exactement comme j'en avais besoin dans mon cas).

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

Vous obtiendrez un 0 si rien n'a été branché et quelque chose> 0 si quelque chose a été branché (même s'il a été branché et retiré depuis) ​​depuis le dernier cycle de mise sous tension ou de redémarrage.

J'espère que cela aide au moins quelqu'un!

0
JxAxMxIxN