Crie um array com todas as interfaces de rede no bash

7

Eu quero criar um array no Bash que contenha todas as interfaces de rede ativas.

Eu consegui criar um loop para imprimi-los, mas quando tento criar o array, ele contém apenas a última lo interface, mas não a outra. Este é o meu código:

#!/bin/bash

for iface in $(ifconfig | cut -d ' ' -f1| tr ':' '\n' | awk NF)
do
           printf "$iface%s\n"
           declare -a array_test=["$iface"]
done
for i in "${array_test[@]}"; do echo "$i"; done

E esta é minha saída:

eno1
eno2
eno3
lo
[lo]

Além disso, como posso excluir a interface lo localhost da matriz?

    
por Georgе Stoyanov 22.12.2017 / 15:12

4 respostas

7

Aqui está uma solução, atribua a lista e adicione o item a ela:

#!/bin/bash

array_test=()
for iface in $(ifconfig | cut -d ' ' -f1| tr ':' '\n' | awk NF)
do
        printf "$iface\n"
        array_test+=("$iface")
done
echo ${array_test[@]}

Se você quiser que a saída exiba um item por linha:

for i in "${array_test[@]}"; do echo "$i"; done

Para remover o host local da saída:

if [ "$iface" != "lo" ] 
then
    array_test+=("$iface")
fi
    
por 22.12.2017 / 15:21
3

Minha tentativa:

readarray -t interfaces < <(ip l | awk -F ":" '/^[0-9]+:/{dev=$2 ; if ( dev !~ /^ lo$/) {print $2}}')
for i in "${interfaces[@]// /}" ; do echo "$i" ; done
    
por 22.12.2017 / 15:59
2

bash construirá uma matriz a partir de qualquer lista delimitada por espaços em branco (espaços, abas, novas linhas) que você fornecer. por exemplo. %código%. Podemos usar a substituição de comando ( array=(a b c) ) para gerar uma lista delimitada por espaços em branco. Por exemplo:

$ ifaces=( $(ip addr list | awk -F': ' '/^[0-9]/ {print $2}') )

e agora imprima a matriz que acabamos de criar:

$ declare -p ifaces
declare -a ifaces=([0]="lo" [1]="eth0" [2]="eth1" [3]="br1" [4]="br0" [5]="ppp0")

Para excluir $() :

$ ifaces=( $(ip addr list | awk -F': ' '/^[0-9]/ && $2 != "lo" {print $2}') )
$ declare -p ifaces
declare -a ifaces=([0]="eth0" [1]="eth1" [2]="br1" [3]="br0" [4]="ppp0")

Se você realmente quiser usar lo em vez de ifconfig , tente o seguinte:

ifaces=( $(ifconfig | awk -F':'  '/^[^ ]*: / && $1 != "lo" {print $1}') )
    
por 23.12.2017 / 07:17
1

ifconfig apenas exibe as interfaces que estão ativas.

No Linux, você pode obter uma lista de interfaces no diretório /sys/class/net . Então, com zsh , você pode fazer:

interfaces=(/sys/class/net/*(DN:t))

Para excluir lo :

set -o extendedglob
interfaces=(/sys/class/net/^lo(DN:t))

Somente para os up , você poderia fazer:

interfaces=(/sys/class/net/*(DNe{'[[ $(<$REPLY/operstate) = up ]]'}:t)

ou, assumindo o valor padrão de $IFS .

interfaces=($(ip -br link | LC_ALL=C awk '$2 == "UP" {print $1}'))

No meu sistema, pelo menos, o status de lo é UNKNOWN, portanto, seria excluído.

Isso também funcionaria com bash , desde que os nomes de interface não contenham caracteres curinga. Nas versões mais recentes do Linux, o IIRC garante que os nomes de interface não contenham a guia space e os caracteres newline (o padrão $IFS ), para que eles não causem problemas. Outros espaços em branco do Unicode são permitidos, portanto, o LC_ALL = C, que deve garantir que awk não será dividido neles.

    
por 23.12.2017 / 18:51