¿Cómo detectar el estado físico conectado de un cable / conector de red?
-
03-07-2019 - |
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:
- Usando 'ifconfig' - ya que un cable de red puede estar conectado pero la red no está configurada correctamente o no está actualmente activa.
- 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!
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
-
Hago todo esto como usuario normal (no root )
-
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 usarsed
.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
-
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
. -
En fin, ya debe haber algo sobre esto ...
Dependiendo de Instalación de Linux , puede agregar scripts
if-up
yif-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!