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


145

Dans un environnement Linux, je dois détecter l'état physique connecté ou déconnecté d'un connecteur RJ45 à sa prise. De préférence en utilisant uniquement les scripts BASH.

Les solutions suivantes qui ont été proposées sur d'autres sites ne fonctionnent PAS à cet effet:

  1. Utilisation de 'ifconfig' - car un câble réseau peut être connecté mais le réseau n'est pas correctement configuré ou n'est pas actuellement actif.
  2. Ping un hôte - puisque le produit sera dans un LAN utilisant une configuration de 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 y est)?

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


Kent Fredric et Lothar , vos deux réponses satisfont mon besoin ... merci beaucoup! Lequel j'utiliserai ... Je ne sais toujours pas.

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

Réponses:


228

Vous voulez regarder les nœuds dans

/ sys / class / net /

J'ai expérimenté le mien:

Fil branché:

eth0/carrier:1
eth0/operstate:unknown

Fil retiré:

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 en toute simplicité:

grep "" eth0/* 

Cela forme une belle liste de key:valuepaires.


8
Notez que comme le dit Marco ci-dessous, l'interface doit être active (même si elle n'est pas configurée) pour interroger ces valeurs.
Jamie Kitson

11
grep "" eth0 / * est si élégant et simple, merci! :) Avec l'option -s, grep ne se plaindra pas des répertoires.
Ray

2
Je préfère:: grep -H . eth0/*Ce whipe emty lines et print nom d'entrée avec appartiennent à chaque ligne.
F.Hauri

Les erreurs sur les répertoires de grep peuvent être ignorées avec:grep -s "" eth0/*
mrtumnus

Notez que l'interface doit être active. Voir la réponse de Marco ci-dessous. Dans mon système, eth0 n'est pas défini par défaut et mon programme génère de manière aléatoire une adresse IP pour celui-ci. Je reçois une erreur "Argument non valide" en cas de chat avec le transporteur
VocoJax

84

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 l'état du lien, vous pouvez utiliser grep:

$ sudo ethtool eth0 | grep Link
    Link detected: yes

lien ip | grep BROADCAST | couper -d ':' -f 2 | tandis que lu i; faire echo $ i; ethtool $ i | grep Link; done
Bryan Hunt

3
Notez que comme le dit Marco ci-dessous, l'interface doit être active (même si elle n'est pas configurée) pour interroger ces valeurs.
Jamie Kitson

C'est génial! J'avais un moyen de vérifier si Ethernet est disponible, si Ethernet est activé, si Ethernet est connecté, mais aucun moyen de vérifier si le câble réel était connecté. grep Linkle fait. Je vous remercie!!
ᴛʜᴇᴘᴀᴛᴇʟ

Je ne travaille pas ici. Ubuntu 16.04 sur le matériel HP. les interfaces non configurées sont «sans lien», même lorsqu'elles sont forcées à l' upétat.
0xF2

26

Utilisez 'ip monitor' pour obtenir les changements d'état des liens en TEMPS RÉEL.


3
Dans mon cas, c'est la seule réponse qui a fonctionné ... / sys / class / net / eth0 / carrier montre toujours 1quand mon câble est déconnecté alors ip monitorqu'il montre réellement quelque chose
Tim Tisdall

Certains développant cette méthode pourraient être remerciés, Peter. Quelque chose comme n'importe quel exemple qui répond à la question initiale sur la connaissance de l'état de la fiche du câble.
Sopalajo de Arrierez

17

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

L'interface doit cependant être active, sinon vous obtiendrez une erreur d'argument non valide.

Alors d'abord:

ifconfig ethX up

Ensuite:

cat /sys/class/net/ethX

4
Essayez "cat / sys / class / net / eth [n] / operstate" où [n] est le numéro de périphérique eth.
pmont

Cela vous indique seulement si eth [n] est en haut, s'il est en panne, cela ne vous indique pas si le câble est connecté ou non.
Brice du

@Brice, en effet, vous voulez vérifier le fichier ethX/carrierqui vaut 1 si le 'carrier' est détecté, c'est-à-dire qu'un câble est connecté et transporte des données ...
Alexis Wilke

Cela a fonctionné pour moi en utilisant les commandes Process Runtime Exec pour vérifier si le câble est connecté sous Android.
Arlyn

Ou, après ifconfig ethX up, ifconfig ethX et recherchez RUNNING.
craig65535

8

Au bas niveau, ces événements peuvent être interceptés à l'aide de sockets rtnetlink , sans aucune interrogation. Remarque: si vous utilisez rtnetlink, vous devez travailler avec udev, sinon votre programme peut être confus lorsque udev renomme une nouvelle interface réseau.

Le problème avec les configurations de réseau avec des scripts shell est que les scripts shell sont terribles pour la gestion des événements (comme un câble réseau connecté et déconnecté). Si vous avez besoin de quelque chose de plus puissant, jetez un œ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 «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, donc normalement, les commandes de configuration se situent entre les deux, 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 retiré, l'adresse IP sera automatiquement supprimée.


4

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

ifplugd et netplugd


J'utilise l' ifplugstatusoutil du ifplugddémon. Pas besoin d'arguments, tapez simplement ifplugstatuset vous obtiendrez tous les NIC branchés ou débranchés.
Sopalajo de Arrierez

3

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 l'utiliser mii-tool, étant donné que vous avez à l'esprit Ethernet.


3
mii-tool a été remplacé par ethtool. mii-tool ne connaît pas les liens GigE.
JimB

en outre, la plupart des serveurs ont des adaptateurs configurés manuellement, qui sont ignorés par NM.
JimB

1
mii-toolsemble être la seule commande qui peut signaler l'état de la liaison lorsque l'interface est en panne.
don réussi le

2

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

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

Si le résultat sera à la hausse ou à la baisse. Parfois, cela montre inconnu, alors vous devez vérifier

eth0/carrier

Il montre 0 ou 1


2

Quelques précisions et astuces

  1. Je fais tout cela en tant qu'utilisateur normal (pas root )

  2. Récupérer les informations de dmesg

    L'utilisation dmesgest l'une des premières choses à faire pour demander l'é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 -n1mais 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. Test autour d'un /syspseudo système de fichiers

    Lire ou écrire sous /syspeut 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, pas d'un véritable suivi des é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 pour quitter la boucle)

    Nota: Cela nécessite patchd'être installé.

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

    En fonction de l' installation Linux , vous pouvez ajouter if-upetif-down des scripts pour être en mesure de réagir à ce genre 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 interfacespour plus d'infos.


Merci pour vos commentaires et vos contributions à ce sujet. Cependant, vous réalisez que ce sont des scripts «automatisés». Au point 2, quand vous dites sortie ' ou ' une autre sortie, ou quand vous dites " selon l'état, le message peut varier en fonction du matériel et des pilotes utilisés " ... c'est vraiment un gros problème. La sortie doit être cohérente ou les scripts de production commencent à se rompre. Mais c'est une bonne information quand même, merci.
Jeach

@Jeach La sortie peut varier signifie: Vous pouvez utiliser un autre pilote quee1000 et l' événement pourrait se produire à un autre moment que936555.596870 , mais vous verrez toujours NIC Link is.
F.Hauri

2

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 de la configuration de l'interface.

C'est juste une autre façon d'obtenir les informations /sys/class/net/eth0/operstate.


Vous avez sauvé mes heures !!
ADITYA VALLURU

1

sur arch linux. (Je ne suis pas sûr sur les autres distributions) vous pouvez voir l'operstate. qui apparaît s'il est connecté ou en panne sinon l'operstate vit

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

ou pour moi devient plus rapide:

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

Il écoutera le fichier syslog.

Résultat (en cas de déconnexion et après 4 secondes de connexion à nouveau):

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

D'une manière ou d'une autre, si vous voulez vérifier si le câble Ethernet est branché sous linux après la recommandation: "ifconfig eth0 down". Je trouve une solution: utilisez l'outil 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

si le câble est connecté, le test de liaison est 0, sinon 1.


0

J'utilisais mon appareil amélioré OpenWRT comme répéteur (qui ajoute des capacités Ethernet virtuel et LAN sans fil) et j'ai trouvé que le transporteur / sys / class / net / eth0 et les valeurs opstate n'étaient pas fiables. J'ai joué avec /sys/class/net/eth0.1 et /sys/class/net/eth0.2 ainsi avec (au moins à ma conclusion) aucun moyen fiable de détecter que quelque chose était physiquement branché et de parler sur tout des ports Ethernet. J'ai trouvé un moyen un peu brut mais apparemment fiable de détecter si quelque chose avait été branché depuis le dernier état de redémarrage / mise sous tension au moins (ce qui fonctionnait 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!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.