Pregunta

En un entorno Linux, necesito detectar el estado físico conectado o desconectado de un conector RJ45 a su zócalo. Preferiblemente usar solo scripts 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á actualmente 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á allí)?

¿Cómo se supone que el mundo de 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 dejarlos a los dos como la respuesta correcta? Y es probablemente justo para ti que yo elija uno. Tirar una moneda, supongo? Una vez más, gracias!

¿Fue útil?

Solución

Quieres ver los nodos en

/sys/class/net/

Experimenté con el mío:

Cable enchufado:

eth0/carrier:1
eth0/operstate:unknown

Cable removido:

eth0/carrier:0
eth0/operstate:down

Cable enchufado de nuevo:

eth0/carrier:1
eth0/operstate:up

Side Trick: cosechando todas las propiedades a la vez de una manera fácil:

grep "" eth0/* 

Esto forma una buena lista de pares key: value .

Otros consejos

Puede 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 puedes usar grep:

$ sudo ethtool eth0 | grep Link
    Link detected: yes

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

cat / sys / class / net / ethX es por 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.

Así que primero:

ifconfig ethX up

Entonces:

cat /sys/class/net/ethX

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

El problema con 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 que se conecta y desconecta). 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, una secuencia de comandos NCD simple que imprimirá el cable " en " y " cable fuera " a la salida estándar (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án 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 está permitida para retroceder ; en el segundo ejemplo, por ejemplo, si se extrae el cable, la dirección IP se eliminará automáticamente.

Existen dos demonios que detectan estos eventos:

ifplugd y netplugd

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

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

Utilizo este comando para verificar que el cable esté conectado:

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

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

eth0/carrier

Muestra 0 o 1

Algunas precisiones y trucos

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

  2. Agarra informaciones de dmesg

    Usar dmesg es una de las primeras cosas que debe hacer para consultar 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 escribirse por dmesg | grep eth. * Link.is | tail -n1 pero prefiero usar 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 de pseudo sistema de archivos / sys

    ¡Leer o escribir en / sys podría dañar tu sistema, especialmente si se ejecuta como root ! Has sido advertido ;-)

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

    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 renderizar algo como (una vez que se haya desconectado y vuelto a conectar, 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 Ingrese para salir del ciclo)

    Nota: Esto requiere que se instale parche .

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

    Dependiendo de Instalación de Linux , puede agregar scripts if-up y if-down para poder reaccionar ante 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
    

    vea man interfaces para obtener más información.

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

o para mi más rápido obtiene:

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

Escuchará el archivo syslog.

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

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

en arch linux. (No estoy seguro en otras distribuciones) puede ver el estado de operación que se muestra si está conectado o si no está activo el estado operstate

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

Usted puede usar ifconfig.

# ifconfig eth0 up
# ifconfig eth0

Si la entrada muestra RUNNING, 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 en / sys / class / net / eth0 / operstate .

Estaba usando mi dispositivo mejorado OpenWRT como repetidor (lo que agrega capacidades de LAN inalámbrica y Ethernet virtual) y descubrí que los valores de operador y opstate / 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 para mi descubrimiento) ninguna forma confiable de detectar que algo estaba físicamente conectado y hablando en cualquier de los puertos ethernet. Descubrí una forma un tanto ruda pero aparentemente confiable para detectar si se había conectado algo desde el último estado de reinicio / encendido (que funcionó exactamente como lo necesitaba en mi caso).

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

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

¡Espero que esto ayude a alguien por lo menos!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top