Pergunta

Em um ambiente Linux, eu preciso detectar o estado ligado ou desligado física de um conector RJ45 para seu soquete. De preferência usando apenas BASH scripting.

As soluções seguintes que foram propostas em outros sites não funcionam para esta finalidade:

  1. Usando 'ifconfig' -., Desde um cabo de rede pode ser conectado, mas a rede não configurado corretamente ou não atualmente up
  2. Ping um host -. Uma vez que o produto estará dentro de uma LAN usando uma configuração de rede desconhecido e hospedeiros desconhecidos

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

Como é o mundo Linux suposto ter sua própria versão da bolha do Windows que surgem a partir da bandeja o ícone indicando que você acabou de desconectar o cabo de rede?


Kent Fredric e Lothar , tanto de suas respostas satisfazer a minha necessidade ... muito obrigado! Qual deles eu vou usar ... Eu ainda não sei.

Eu acho que não pode colocá-lo tanto para baixo como a resposta correta? E seu provavelmente justo para você que eu escolher um. Jogue uma moeda eu acho? Mais uma vez, obrigado!

Foi útil?

Solução

Você quer olhar para o nós em

/sys/class/net/

Eu experimentei com 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 Side: colhendo todas as propriedades de uma vez o caminho mais fácil:

grep "" eth0/* 

Isso forma uma boa lista de pares key:value.

Outras dicas

Você pode 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 só obter o status do link que você pode usar grep:

$ sudo ethtool eth0 | grep Link
    Link detected: yes

Use 'do monitor do IP' para obter TEMPO REAL alterações do estado do link.

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

A interface tem que ser-se, porém, mais você receberá um erro de argumento inválido.

Então, primeiro:

ifconfig ethX up

Depois:

cat /sys/class/net/ethX

No nível baixo, esses eventos podem ser capturados usando rtnetlink soquetes, sem qualquer votação. nota: se você usar rtnetlink, você tem que trabalhar em conjunto com udev, ou o seu programa pode ficar confuso quando udev renomeia uma nova interface de rede

.

O problema em fazer as configurações de rede com scripts shell é que scripts shell são terríveis para o tratamento de eventos (como um cabo de rede a ser conectada e out). Se você precisar de algo mais poderoso, dê uma olhada no meu NCD linguagem de programação , um linguagem de programação projetada para configurações de rede.

Por exemplo, um simples NCD script que irá imprimir "cabo" e "cabo para fora" para stdout (assumindo que a interface já está instalado):

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, usos net.backend.waitlink() rtnetlink e usos net.backend.waitdevice() udev)

A idéia de NCD é que você usá-lo exclusivamente para configurar a rede, por isso normalmente, comandos de configuração viria no meio, tais 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 notar é que a execução é permitida a regress ; No segundo exemplo, por exemplo, se o cabo é puxado para fora, o endereço IP será automaticamente removido.

Existem dois daemons que detectam estes eventos:

ifplugd e netplugd

A maioria das distribuições Linux modernas usar NetworkManager para isso. Você poderia usar D-BUS para escutar para os eventos.

Se você quer uma ferramenta de linha de comando para verificar o status, você também pode usar mii-tool, dado que você tem Ethernet em mente.

Eu uso este comando para verificar um fio é conectado:

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

Se o resultado será para cima ou para baixo. Às vezes, ele mostra desconhecido, então você precisa verificar

eth0/carrier

Ele mostra 0 ou 1

Algumas precisões e truques

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

  2. informações sobre Grab de dmesg

    Usando dmesg é um dos 1º coisas a fazer para inquirir 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 os drivers utilizados.

    Nota:. Isso poderia por dmesg|grep eth.*Link.is|tail -n1 escrito, mas 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. Test torno /sys pseudo sistema de arquivos

    Leitura ou escrita sob /syscould quebrar seu sistema, especialmente se Executar como root ! Você foi avisado; -)

    Este é um método de agrupamento, não um real acompanhamento 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
    

    poderia tornar algo como (uma vez que você desligado e ligado de volta, 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
    

    (Hit Enter para fazer um loop de saída)

    Nota: Isso requer patch para ser instalado

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

    Dependendo Instalação Linux , você pode adicionar scripts if-up e if-down para ser capaz de reagir a este tipo de eventos.

    Em Debian com base (como 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
    

    ver man interfaces para mais infos.

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

ou para mim mais rápido fica:

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

Ele vai ouvir o arquivo syslog.

Resultado (se desligue e depois de 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

no Arch Linux. (Im não tem certeza sobre outras distros), você pode ver o operstate. que aparece se conectados ou para baixo se não as vidas operstate sobre

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

Você pode uso ifconfig.

# ifconfig eth0 up
# ifconfig eth0

Se os shows entrada em execução, a interface está fisicamente conectado. Isto irá ser mostrado, independentemente, se a interface estiver configurada.

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

Eu estava usando meu dispositivo melhorado OpenWRT como um repetidor (que adiciona ethernet virtual e recursos de rede sem fios) e descobriu que o / sys / class / transportadora net / eth0 e valores opstate não eram fiáveis. Eu brinquei com /sys/class/net/eth0.1 e /sys/class/net/eth0.2 bem com (pelo menos para a minha descoberta) nenhuma maneira confiável para detectar que algo estava fisicamente conectado e falando em qualquer das portas Ethernet. Eu descobri um pouco bruto, mas forma aparentemente confiável para detectar se alguma coisa tinha sido ligado desde o último estado de reinicialização / poweron 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 foi conectado e algo> 0 se alguma coisa foi conectado (mesmo que tenha sido ligado e uma vez removido) desde a última ligar ou ciclo de reinicialização.

Espero que isso ajude alguém, pelo menos!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top