Я пытаюсь создать сценарий bash, который создает массив имен устройств Ethernet на моем ПК, а не на беспроводной карте. Я хочу иметь список имен, чтобы позже перебирать их.
Например, предположим, что у меня есть два сетевых адаптера Ethernet — enp2s0 и enp3s0 и беспроводная карта — wlp4s0.
От lscpi я бы посмотрел
02:00.0 Ethernet controller: <truncated>
03:00.0 Ethernet controller: <truncated>
04:00.0 Network controller: Intel Corporation Wireless
Аналогично ip a показывает
1: lo: <truncated>
2: enp2s0: <truncated>
3: enp3s0: <truncated>
4: wlp4s0: <truncated>
Как я могу создать массив имен, чтобы я мог перебирать их?
enp2s0
enp3s0
Я понял, как найти первую сетевую карту, используя
NIC=$(basename $(udevadm info -e | grep "DEVPATH=.*$(lspci | grep -m 1 Ethernet | cut -f 1 -d\ )/net" | cut -f 2 -d\ ))
Но я не могу понять, как зациклить этот подход. Любые предложения, как я могу сделать это в bash?
Спасибо
Денша





for f in $(ip a | grep enp | awk '{print $2}' | cut -d":" -f1)
do
<something with $f>
done
Для устройств, которые не начинаются с «enp», альтернатива приведена ниже:
for f in $(ip a | grep -B1 "ether" | grep -v ether | awk '{print $2}' | cut -d":" -f1)
do
<something with $f>
done
nmcli имеет вывод, который можно легко проанализировать, но вам, возможно, придется сначала его установить.
Пример вывода nmcli device:
DEVICE TYPE STATE CONNECTION
eno1 ethernet connected wired connection
wlp2s0 wifi unavailable --
lo loopback unmanaged --
Чтобы извлечь только имена устройств Ethernet, используйте
nmcli device | awk '$2= = "ethernet" {print $1}'
В этом примере вывод будет eno1. Вы можете использовать команду в цикле, как обычно:
for device in $(nmcli device | awk '$2= = "ethernet" {print $1}'); do
# stuff
done
Спасибо с предложениями, которые я изменил свой оригинал на
for DEV in $(lspci | grep Ethernet | cut -f 1 -d\ )
do
NIC=$(basename $(udevadm info -e | grep "DEVPATH=.*$DEV/net" | cut -f 2 -d\ ))
echo $NIC
done
Спасибо за предложения
Попробуйте time udevadm info -e | grep "DEVPATH=.*$DEV/net/" и time ip l | sed 's/^ *[0-9]\+: \([^ ]\+\):.*/\1/p;d' сравнить!
Но если вы предпочитаете команду рядом с ядром, U может: /bin/ls /sys/class/net/
Последний дистрибутив Linux использует набор iproute2 для управления сетями.
Основная команда для вывода списка устройств — ip link show, которую можно сократить до ip l.
ip l | sed 's/^ *[0-9]\+: \([^ ]\+\):.*/\1/p;d'
может вернуться:
lo
eth0
типичный вывод ip l (можно записать: ip links show) выглядит так:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether b8:27:eb:5f:b0:eb brd ff:ff:ff:ff:ff:ff
sed команда будет,
s///)*)[0-9]\+:)\([^ ]\+\))/\1/)p);dЧтобы сделать что-то с $iface в цикле, вы можете написать:
shopt -s extglob
while IFS=$' :\t\r\n' read num iface line;do
if [ "$num" ] && [ -z "${num//*([0-9])}" ] && [ "$iface" ] ;then
echo Doing something with $iface
fi
done < <(ip l)
...
Doing something with lo
Doing something with eth0
Этот небольшой цикл напечатает 1 строку для каждого IPv4-адреса каждого интерфейса. (неиспользуемый или ненастроенный интерфейс отображаться не будет):
while IFS=$' :\t\r\n' read p1 p2 line ;do
[ "$p1" ] && {
[ -z "${p1//*([0-9])}" ] && [ "$p2" ] && crtif=$p2
if [ -z "${p1/inet}" ] ;then
echo Doing something with $crtif having ip $p2
fi
}
done < <(ip a)
Doing something with lo having ip 127.0.0.1/8
Doing something with eth0 having ip 192.168.1.35/24
Извините, я забыл упомянуть, что хочу работать на системах с разными именами устройств, а не на всех enp*.