Como detectar o estado físico conectado de um cabo / conector de rede?


145

Em um ambiente Linux, preciso detectar o estado físico conectado ou desconectado de um conector RJ45 em seu soquete. De preferência, usando apenas scripts BASH.

As seguintes soluções propostas em outros sites NÃO funcionam para esse fim:

  1. Usando 'ifconfig' - já que um cabo de rede pode estar conectado, mas a rede não está configurada corretamente ou não está ativa no momento.
  2. Faça ping em um host - pois o produto estará em uma LAN usando uma configuração de rede desconhecida e hosts desconhecidos.

Não existe algum estado que possa ser usado no sistema de arquivos / proc (tudo o resto está lá)?

Como o mundo do Linux deve ter sua própria versão do balão do Windows que aparece na bandeja de ícones, indicando que você acabou de desconectar o cabo de rede?


Kent Fredric e lothar , suas duas respostas satisfazem minha necessidade ... muito obrigado! Qual deles eu vou usar ... ainda não sei.

Eu acho que não posso colocar vocês dois como a resposta correta? E provavelmente é justo para você que eu escolha um. Jogue uma moeda, eu acho? Mais uma vez, obrigado!

Respostas:


228

Você deseja examinar os nós em

/ sys / class / net /

Eu experimentei o meu:

Fio conectado:

eth0/carrier:1
eth0/operstate:unknown

Fio removido:

eth0/carrier:0
eth0/operstate:down

Fio conectado novamente:

eth0/carrier:1
eth0/operstate:up

Truque lateral: coletando todas as propriedades de uma só vez da maneira mais fácil:

grep "" eth0/* 

Isso forma uma boa lista de key:valuepares.


8
Observe que, como Marco diz abaixo, a interface deve estar ativa (mesmo que não esteja configurada) para consultar esses valores.
Jamie Kitson

11
grep "" eth0 / * é tão elegante e fácil, obrigado! :) Com a opção -s, o grep não irá reclamar dos diretórios.
Raio

2
Eu prefiro:: grep -H . eth0/*Esse chicote de linhas vazias e o nome da entrada impressa pertencem a cada linha.
F. Hauri

Os erros sobre diretórios do grep podem ser ignorados com:grep -s "" eth0/*
mrtumnus

Observe que a interface precisa estar ativa. Veja a resposta de Marco abaixo. No meu sistema, eth0 não está definido por padrão e meu programa gera aleatoriamente um endereço IP para ele. Eu recebo um erro "argumento inválido" de catting a transportadora
VocoJax

84

Você pode usar o 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 obter apenas o status do Link, você pode usar o grep:

$ sudo ethtool eth0 | grep Link
    Link detected: yes

link ip | grep BROADCAST | cut -d ':' -f 2 | enquanto lê i; ecoam $ i; ethtool $ i | grep Link; feito #
Bryan Hunt

3
Observe que, como Marco diz abaixo, a interface deve estar ativa (mesmo que não esteja configurada) para consultar esses valores.
Jamie Kitson

isso é incrível! Eu tinha uma maneira de verificar se a Ethernet está disponível, se a Ethernet está ativada, se a Ethernet está conectada, mas não há como verificar se o cabo real estava conectado. grep Linkfaz isso. Obrigado!!
ᴛʜᴇᴘᴀᴛᴇʟ

Não está trabalhando aqui. Ubuntu 16.04 no hardware HP. interfaces não configuradas são "sem link", mesmo quando forçadas a updeclarar.
0xF2

26

Use 'ip monitor' para obter alterações no estado do link em TEMPO REAL.


3
No meu caso, esta é a única resposta que trabalhou ... / sys / class / net / eth0 / transportadora ainda mostra 1quando o meu cabo está desconectado enquanto ip monitorna verdade mostra algo
Tim Tisdall

Alguma expansão nesse método poderia ser agradecida, Peter. Algo como qualquer exemplo que responda à pergunta original sobre o estado do plugue do cabo.
Sopalajo de Arrierez 01/04/19

17

cat /sys/class/net/ethX é de longe o método mais fácil.

A interface precisa estar ativa, caso contrário, você receberá um erro de argumento inválido.

Então primeiro:

ifconfig ethX up

Então:

cat /sys/class/net/ethX

4
Tente "cat / sys / class / net / eth [n] / operstate", onde [n] é o número do dispositivo eth.
pmont

Isso informa apenas se eth [n] está ativo. Se estiver inativo, não informa se o cabo está conectado ou não.
Brice

@Brice, de fato, que pretende verificar arquivo ethX/carrierque é 1 se for detectado o 'transportador', o que significa que um cabo é conectado e carregando dados ...
Alexis Wilke

Isso funcionou para mim usando os comandos do Process Runtime Exec para verificar se o cabo está conectado no Android.
Arlyn #

Ou, após ifconfig ethX ativado, ifconfig ethX e procure RUNNING.
craig65535

8

No nível baixo, esses eventos podem ser capturados usando soquetes rtnetlink , sem nenhuma pesquisa. Nota lateral: se você usar o rtnetlink, precisará trabalhar em conjunto com o udev ou seu programa poderá ficar confuso quando o udev renomear uma nova interface de rede.

O problema em fazer configurações de rede com scripts de shell é que os scripts de shell são terríveis para o tratamento de eventos (como um cabo de rede sendo conectado e retirado). Se você precisar de algo mais poderoso, dê uma olhada na minha linguagem de programação NCD , uma linguagem de programação projetada para configurações de rede.

Por exemplo, um script NCD simples que imprime "cable in" e "cable out" em stdout (assumindo que a interface já esteja ativa):

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

A idéia do NCD é que você o utilize exclusivamente para configurar a rede; portanto, normalmente, os comandos de configuração são intermediários, 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");
}

A parte importante a ser observada é que a execução pode regredir ; no segundo exemplo, por exemplo, se o cabo for puxado, o endereço IP será removido automaticamente.


4

Existem dois daemons que detectam esses eventos:

ifplugd e netplugd


Eu uso a ifplugstatusferramenta do ifplugddaemon. Não há necessidade de argumentos, basta digitar ifplugstatuse você receberá toda a NIC como conectada ou desconectada.
Sopalajo de Arrierez 28/05

3

As distribuições Linux mais modernas usam o NetworkManager para isso. Você pode usar o D-BUS para ouvir os eventos.

Se você deseja que uma ferramenta de linha de comando verifique o status, também pode usar mii-tool, desde que tenha em mente a Ethernet.


3
O mii-tool foi substituído pelo ethtool. O mii-tool desconhece os links GigE.
JimB

Além disso, a maioria dos servidores possui adaptadores configurados manualmente, que são ignorados pelo NM.
JimB

1
mii-toolparece ser o único comando que pode relatar o status do link quando a interface está inoperante.
precisa saber é o seguinte

2

Eu uso este comando para verificar se um fio está conectado:

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

Se o resultado for alto ou baixo. Às vezes, mostra desconhecido, então você precisa verificar

eth0/carrier

Mostra 0 ou 1


2

Algumas precisões e truques

  1. Eu faço tudo isso como usuário normal (não root )

  2. Obter informações de dmesg

    Usar dmesgé uma das primeiras coisas a fazer para consultar o estado atual do sistema:

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

    poderia responder algo como:

    [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
    

    dependendo do estado, a mensagem pode variar dependendo do hardware e dos drivers usados.

    Nota: isso poderia ser escrito, dmesg|grep eth.*Link.is|tail -n1mas eu prefiro 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. Teste em torno de /syspseudo sistema de arquivos

    Ler ou escrever abaixo /syspode danificar seu sistema, especialmente se for executado como root ! Voce foi avisado ;-)

    Este é um método de agrupamento, não um rastreamento de evento real .

    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
    

    Pode renderizar algo como (depois de desconectar e reconectar, dependendo):

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

    (Pressione Enterpara sair do loop)

    Nota: Isso requer patcha instalação.

  4. Em suma, já deve haver algo sobre isso ...

    Dependendo Instalação Linux , você pode adicionar if-upe if-downscripts para ser capaz de reagir a este tipo de eventos.

    No Debian (como o Ubuntu ), você pode armazenar seus scripts em

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

    veja man interfacespara mais informações.


Obrigado por seus comentários e opiniões sobre o assunto. Embora você perceba que esses são scripts 'automatizados'. No ponto 2, quando você diz saída ' ou ' outra saída, ou quando diz " dependendo do estado, a mensagem pode variar dependendo do hardware e dos drivers usados " ... esse é um grande problema. A saída deve ser consistente ou os scripts de produção começam a ser interrompidos. Mas é uma boa informação independentemente, obrigado.
Jeach

A saída do @Jeach pode variar em média: Você pode usar outro drivere1000 e a noite pode ocorrer em outro momento936555.596870 , mas você sempre verá NIC Link is.
Hauri

2

Você pode usar o ifconfig.

# ifconfig eth0 up
# ifconfig eth0

Se a entrada mostrar RUNNING, a interface está fisicamente conectada. Isso será mostrado independentemente de a interface estar configurada.

Esta é apenas outra maneira de obter as informações /sys/class/net/eth0/operstate.


Você salvou minhas horas !!
ADITYA VALLURU

1

no arch linux. (não tenho certeza de outras distros), você pode visualizar o estado oposto. que aparece se conectado ou desativado, se não o operstate vive

/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 para mim fica mais rápido:

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

Ele ouvirá o arquivo syslog.

Resultado (se desconectar e após 4 segundos conectar novamente):

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

De alguma forma, se você quiser verificar se o cabo ethernet conectou o linux após a recomendação: "ifconfig eth0 down". Eu encontro uma solução: use a ferramenta 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

se o cabo estiver conectado, o teste de link será 0, caso contrário, será 1.


0

Eu estava usando meu dispositivo aprimorado OpenWRT como repetidor (que adiciona recursos de Ethernet virtual e LAN sem fio) e descobri que os valores da operadora / sys / class / net / eth0 e da operadora não eram confiáveis. Eu brinquei com o /sys/class/net/eth0.1 e /sys/class/net/eth0.2, bem como (pelo menos para a minha descoberta) nenhuma maneira confiável de detectar se algo estava fisicamente conectado e falando em qualquer das portas Ethernet. Eu descobri uma maneira um tanto grosseira, mas aparentemente confiável, de detectar se alguma coisa havia sido conectada desde o último estado de reinicialização / inicialização, pelo menos (que funcionou exatamente como eu precisava no meu caso).

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

Você receberá um 0 se nada estiver conectado e algo> 0 se alguma coisa estiver conectada (mesmo que tenha sido conectada e removida) desde o último ciclo de inicialização ou reinicialização.

Espero que isso ajude alguém, pelo menos!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.