Usando um único comando para encontrar a velocidade da NIC

2

Você conhece um único comando de linha para capturar a velocidade do NIC da interface primária do servidor.

Por exemplo, para eth0

  • Obter o nome do host usando uname -n
  • Obtenha seu IP usando nslookup 'uname -n'
  • Pesquise o IP em ifconfig output para saber em qual interface ele está configurado
  • Usando ethtool <interface captured in above command> | grep -i speed

Todos os comandos acima podem ser executados em um único comando?

    
por Venom 30.04.2015 / 21:36

1 resposta

6

Tente:

cat /sys/class/net/eth0/speed

Não tenho certeza do que você quer dizer com interface principal. Em um host com uma pilha IPv4, você pode recuperar a interface onde está a primeira rota padrão:

ip route show 0/0 | grep -Pom1 'dev +\K[^ ]+'

(assumindo o GNU grep ). Então:

cat "/sys/class/net/$(ip route show 0/0 | grep -Pom1 'dev +\K[^ ]+')/speed"

Nem todos os hosts conectados ao IPv4 têm uma rota padrão. Você pode preferir uma interface pela qual acessar um determinado host, como um conhecido como 8.8.8.8 ou já que você está executando esses comandos acima de ssh , o endereço IP de onde vemos a conexão ssh vindo (supondo você está se conectando via IPv4 e não IPv6):

ip route show to match "${SSH_CLIENT%% *}" | grep -Pom1 'dev +\K[^ ]+'

Claro que isso não funciona se essa interface não for uma interface ethernet (é comum ter uma interface bridge nos servidores, por exemplo).

Como uma heurística diferente, você poderia obter o nome da interface não virtual que está ativa, que tem uma velocidade e que transmitiu o maior número de pacotes com algo como:

readlink -f /sys/class/net/* | awk -F / '
   $4 != "virtual" && \
     getline speed < ($0 "/speed") && \
     getline state < ($0 "/operstate") && \
     state == "up" && \
     getline tx < ($0 "/statistics/tx_packets") {
       if (tx > max) {returned_speed=speed; max=tx}
     }
   END{print returned_speed}'

Por fim, um comentário sobre você solicitando um único comando: observe que o sh in ssh é para shell . Portanto, o código executado na máquina remota é código shell. Você pode executar vários comandos e scripts multi-line lá. A coisa a lembrar, porém, é que o código é interpretado pelo shell de login do usuário remoto, que não é garantido como Bourne-like (embora na prática hoje em dia em sistemas baseados em Linux geralmente é). Então você pode fazer por exemplo:

remote_code=$(cat << \end_of_script
  readlink -f /sys/class/net/* | awk -F / '
     $4 != "virtual" && \
       getline speed < ($0 "/speed") && \
       getline state < ($0 "/operstate") && \
       state == "up" && \
       getline tx < ($0 "/statistics/tx_packets") {
         if (tx > max) {returned_speed=speed; max=tx}
       }
     END{print returned_speed}'
end_of_script
)

for host in host1 host2 host3; do
  speed=$(ssh "$host" "$remote_code")
  printf '%20s: %s\n' "$host" "$speed"
done

Esse remote_code acima está em uma sintaxe compatível com shells das famílias Bourne, rc e fish , mas não (t)csh .

    
por 30.04.2015 / 21:52