¿Cómo detectar el estado físico conectado de un cable / conector de red?

145

En un entorno Linux, necesito detectar el estado físico conectado o desconectado de un conector RJ45 a su zócalo. Preferiblemente utilizando solo secuencias de comandos BASH.

Las siguientes soluciones que se han propuesto en otros sitios NO funcionan para este propósito:

  1. Usando 'ifconfig' - ya que un cable de red puede estar conectado pero la red no está configurada correctamente o no está activa
  2. Haga ping a un host, ya que el producto estará dentro de una LAN utilizando una configuración de red desconocida y hosts desconocidos.

¿No hay algún estado que pueda usarse en el sistema de archivos / proc (todo lo demás está ahí)?

¿Cómo se supone que el mundo Linux tiene su propia versión de la burbuja de Windows que aparece en la bandeja de iconos que indica que acaba de desconectar el cable de red?


Kent Fredric y lothar , ambas respuestas satisfacen mi necesidad ... ¡muchas gracias! Cuál usaré ... Todavía no lo sé.

¿Supongo que no puedo ponerlos a ambos como la respuesta correcta? Y probablemente sea justo para ti que yo elija uno. ¿Lanzar una moneda, supongo? ¡Gracias otra véz!

Jeach
fuente

Respuestas:

228

Desea mirar los nodos en

/ sys / class / net /

Experimenté con el mío:

Alambre enchufado:

eth0/carrier:1
eth0/operstate:unknown

Alambre eliminado:

eth0/carrier:0
eth0/operstate:down

Cable enchufado de nuevo:

eth0/carrier:1
eth0/operstate:up

Truco lateral: cosechar todas las propiedades a la vez de la manera fácil:

grep "" eth0/* 

Esto forma una buena lista de key:valuepares.

Kent Fredric
fuente
8
Tenga en cuenta que, como dice Marco a continuación, la interfaz debe estar activa (incluso si no está configurada) para consultar estos valores.
Jamie Kitson
11
grep "" eth0 / * es tan elegante y fácil, ¡gracias! :) Con el modificador -s grep no se quejará de los directorios.
Rayo
2
Prefiero:: grep -H . eth0/*este tipo de líneas vacías y el nombre de la entrada de impresión pertenecen a cada línea.
F. Hauri
Los errores sobre los directorios de grep pueden ignorarse con:grep -s "" eth0/*
mrtumnus
Tenga en cuenta que la interfaz tiene que estar activa. Vea la respuesta de Marco a continuación. En mi sistema, eth0 no está configurado de manera predeterminada y mi programa genera aleatoriamente una dirección IP para él. Recibo un error de "argumento no válido" al atrapar al transportista
VocoJax
84

Puedes usar 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

Para obtener solo el estado del enlace, puede usar grep:

$ sudo ethtool eth0 | grep Link
    Link detected: yes
lothar
fuente
enlace ip | grep BROADCAST | cut -d ':' -f 2 | mientras lee i; hacer eco $ i; ethtool $ i | grep Link; hecho
Bryan Hunt
3
Tenga en cuenta que, como dice Marco a continuación, la interfaz debe estar activa (incluso si no está configurada) para consultar estos valores.
Jamie Kitson
esto es asombroso! Tenía una manera de verificar si Ethernet está disponible, si Ethernet está habilitada, si Ethernet está conectada, pero no hay manera de verificar si el cable real estaba conectado. grep Linklo hace. ¡¡Gracias!!
ᴛʜᴇᴘᴀᴛᴇʟ
No estoy trabajando aquí. Ubuntu 16.04 en hardware HP. las interfaces no configuradas son "sin enlace", incluso cuando se las obliga a updeclarar.
0xF2
26

Use 'monitor ip' para obtener cambios de estado del enlace en TIEMPO REAL.

Peter Quiring
fuente
3
En mi caso, esta es la única respuesta que funcionó ... / sys / class / net / eth0 / carrier todavía se muestra 1cuando mi cable está desconectado mientras ip monitorrealmente muestra algo
Tim Tisdall
Se podría agradecer a algunos que hayan ampliado este método, Peter. Algo así como cualquier ejemplo que responda a la pregunta original sobre conocer el estado del enchufe del cable.
Sopalajo de Arrierez
17

cat /sys/class/net/ethX Es, con mucho, el método más fácil.

Sin embargo, la interfaz debe estar activada, de lo contrario obtendrá un error de argumento no válido.

Entonces primero:

ifconfig ethX up

Luego:

cat /sys/class/net/ethX
Marco
fuente
44
Pruebe "cat / sys / class / net / eth [n] / operstate" donde [n] es el número del dispositivo eth.
pmont
Esto solo le dice si eth [n] está arriba, si está abajo no le dice si el cable está conectado o no.
Brice
@Brice, de hecho, desea verificar el archivo ethX/carrierque es 1 si se detecta el 'operador', lo que significa que hay un cable conectado y que transporta datos ...
Alexis Wilke
Esto funcionó para mí usando los comandos de Process Runtime Exec para verificar si el cable está conectado en Android.
Arlyn
O, después de ifconfig ethX, ifconfig ethX y busque RUNNING.
craig65535
8

En el nivel bajo, estos eventos pueden capturarse utilizando sockets rtnetlink , sin ningún sondeo. Nota al margen: si usa rtnetlink, debe trabajar junto con udev, o su programa puede confundirse cuando udev cambia el nombre de una nueva interfaz de red.

El problema al hacer configuraciones de red con scripts de shell es que los scripts de shell son terribles para el manejo de eventos (como un cable de red conectado y desconectado). Si necesita algo más potente, eche un vistazo a mi lenguaje de programación NCD , un lenguaje de programación diseñado para configuraciones de red.

Por ejemplo, un simple script NCD que imprimirá "cable in" y "cable out" en stdout (suponiendo que la interfaz ya esté activa):

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 y net.backend.waitdevice()usa udev)

La idea de NCD es que lo use exclusivamente para configurar la red, por lo que normalmente, los comandos de configuración se interpondrían entre ellos, como:

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 a tener en cuenta es que la ejecución puede retroceder ; en el segundo ejemplo, por ejemplo, si se extrae el cable, la dirección IP se eliminará automáticamente.

Ambroz Bizjak
fuente
4

Existen dos demonios que detectan estos eventos:

ifplugd y netplugd

alemán
fuente
Yo uso la ifplugstatusherramienta del ifplugddemonio. No necesita argumentos, simplemente escriba ifplugstatusy obtendrá toda la NIC como conectada o desconectada.
Sopalajo de Arrierez
3

La mayoría de las distribuciones modernas de Linux usan NetworkManager para esto. Podrías usar D-BUS para escuchar los eventos.

Si desea que una herramienta de línea de comandos verifique el estado, también puede usarla mii-tool, dado que tiene en mente Ethernet.

andri
fuente
3
mii-tool ha sido reemplazado por ethtool. mii-tool desconoce los enlaces GigE.
JimB
Además, la mayoría de los servidores tienen adaptadores configurados manualmente, que NM ignora.
JimB
1
mii-toolparece ser el único comando que puede informar sobre el estado del enlace cuando la interfaz está inactiva.
donothings exitosamente
2

Uso este comando para verificar que un cable esté conectado:

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

Si el resultado será arriba o abajo. A veces se muestra desconocido, entonces debe verificar

eth0/carrier

Muestra 0 o 1

Sarvar Nishonboev
fuente
2

Algunas precisiones y trucos

  1. Hago todo esto como usuario normal (no root )

  2. Agarra información de dmesg

    Usar dmesges una de las primeras cosas que debe hacer para consultar el estado actual del sistema:

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

    podría responder algo como:

    [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
    

    según el estado, el mensaje puede variar según el hardware y los controladores utilizados.

    Nota: esto podría ser escrito dmesg|grep eth.*Link.is|tail -n1pero prefiero usarlo 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. Prueba alrededor del /syspseudo sistema de archivos

    Leer o escribir debajo /syspodría dañar su sistema, ¡especialmente si se ejecuta como root ! Has sido advertido ;-)

    Este es un método de agrupación, no un seguimiento de eventos reales .

    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
    

    Podría representar algo como (una vez que haya desenchufado y enchufado de nuevo, dependiendo):

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

    (Presione Enterpara salir del bucle)

    Nota: Esto requiere patchser instalado.

  4. En fin, ya debe haber algo sobre esto ...

    Dependiendo de la instalación de Linux , puede agregar if-upy if-downsecuencias de comandos para poder reaccionar a este tipo de eventos.

    En Debian (como Ubuntu ), puede almacenar sus scripts en

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

    ver man interfacespara más información.

F. Hauri
fuente
Gracias por sus comentarios y aportes al respecto. Sin embargo, te das cuenta de que estos son scripts 'automatizados'. En el punto 2, cuando dice salida ' u ' otra salida, o cuando dice " dependiendo del estado, el mensaje puede variar según el hardware y los controladores utilizados " ... ese es un gran problema. La salida debe ser coherente o los scripts de producción comienzan a romperse. Pero es buena información independientemente, gracias.
Jeach
@Jeach La salida puede variar: significa que puede usar otro controladore1000 y podría ocurrir un evento en otro momento936555.596870 , pero de todos modos verá NIC Link is.
F. Hauri
2

Usted puede utilizar ifconfig.

# ifconfig eth0 up
# ifconfig eth0

Si la entrada muestra EN EJECUCIÓN, la interfaz está físicamente conectada. Esto se mostrará independientemente de si la interfaz está configurada.

Esta es solo otra forma de obtener la información /sys/class/net/eth0/operstate.

craig65535
fuente
¡Me salvaste las horas!
ADITYA VALLURU
1

en el arco de linux. (No estoy seguro en otras distribuciones) puede ver el estado operativo. que aparece si está conectado o abajo si no el estado operativo sigue vivo

/sys/class/net/(interface name here)/operstate
#you can also put watch 
watch -d -n -1 /sys/class/net/(interface name here)/operstate
Skrmnghrd
fuente
1
tail -f /var/log/syslog | grep -E 'link (up|down)'

o para mí más rápido consigue:

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

Escuchará el archivo syslog.

Resultado (si se desconecta y después de 4 segundos se vuelve a conectar):

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
Dima
fuente
1

De alguna manera, si desea verificar si el cable de Ethernet se conectó a Linux después del comando: "ifconfig eth0 down". Encuentro una solución: use la herramienta 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 el cable está conectado, la prueba de enlace es 0, de lo contrario es 1.

kyzrong
fuente
0

Estaba usando mi dispositivo mejorado OpenWRT como repetidor (que agrega capacidades virtuales de ethernet y LAN inalámbrica) y descubrí que los valores de operador / opsato / sys / class / net / eth0 no eran confiables. Jugué con /sys/class/net/eth0.1 y /sys/class/net/eth0.2 también con (al menos en mi opinión) ninguna forma confiable de detectar que algo estaba conectado físicamente y hablando en cualquier de los puertos ethernet. Descubrí una forma un poco cruda pero aparentemente confiable de detectar si algo se había conectado desde el último estado de reinicio / encendido al menos (que funcionó exactamente como lo necesitaba en mi caso).

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

Obtendrá un 0 si no se ha conectado nada y algo> 0 si se ha conectado algo (incluso si se conectó y se retiró) desde el último ciclo de encendido o reinicio.

Espero que esto ayude a alguien al menos!

JxAxMxIxN
fuente