Create an array with all network interfaces in bash
Solution 1
Here is a solution, assign the list and then add item to it:
#!/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[@]}
If you want the output displayed one item per line:
for i in "${array_test[@]}"; do echo "$i"; done
To remove localhost from output:
if [ "$iface" != "lo" ]
then
array_test+=("$iface")
fi
Solution 2
My try:
readarray -t interfaces < <(ip l | awk -F ":" '/^[0-9]+:/{dev=$2 ; if ( dev !~ /^ lo$/) {print $2}}')
for i in "${interfaces[@]// /}" ; do echo "$i" ; done
Solution 3
ifconfig
only outputs the interfaces that are up.
On Linux, you can get a list of interfaces in the /sys/class/net
directory. So, with zsh
, you can do:
interfaces=(/sys/class/net/*(DN:t))
To exclude lo
:
set -o extendedglob
interfaces=(/sys/class/net/^lo(DN:t))
For only the up
ones, you could do:
interfaces=(/sys/class/net/*(DNe{'[[ $(<$REPLY/operstate) = up ]]'}:t)
or, assuming the default value of $IFS
.
interfaces=($(ip -br link | LC_ALL=C awk '$2 == "UP" {print $1}'))
On my system at least the status for lo
is UNKNOWN so would be excluded.
That would also work with bash
provided interface names don't contain wildcard characters. In recent versions of Linux, IIRC, interface names are guaranteed not to contain space tab and newline characters (the default $IFS
), so those would not cause problem. Other Unicode blanks are allowed though, hence the LC_ALL=C which should guarantee that awk
won't split on those.
Solution 4
bash
will construct an array from any white-space delimited (spaces, tabs, newlines) list you give it. e.g. array=(a b c)
. We can use command substitution ($()
) to generate such a white-space delimited list. For example:
$ ifaces=( $(ip addr list | awk -F': ' '/^[0-9]/ {print $2}') )
and now print out the array we just created:
$ declare -p ifaces
declare -a ifaces=([0]="lo" [1]="eth0" [2]="eth1" [3]="br1" [4]="br0" [5]="ppp0")
To exclude lo
:
$ 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")
If you really want to use ifconfig
rather than ip
, try this:
ifaces=( $(ifconfig | awk -F':' '/^[^ ]*: / && $1 != "lo" {print $1}') )
Solution 5
If you have '-j' support for ip
(json output) then use the excellent jq
utility;
# ip -j addr show | jq -r .[].ifname
lo
eth0
eth1
tunl0
gre0
gretap0
erspan0
ip_vti0
ip6_vti0
sit0
ip6tnl0
ip6gre0
dummy0
kube-ipvs0
cbr0
vethfbcab624
(example from a kubernetes node)
Related videos on Youtube
Georgi Stoyanov
Updated on September 18, 2022Comments
-
Georgi Stoyanov over 1 year
I want to create an array in Bash which to contain all active network interfaces.
I have managed to create a for loop printing them but when I try to create the array, it just contains the last
lo
interface but not the other. This is my code:#!/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
And this is my output:
eno1 eno2 eno3 lo [lo]
Also, how can I exclude the lo localhost interface from the array?
-
Alessio over 6 years@peterh
bash
can be used for quite complex scripts (as can, e.g.,ksh
orzsh
)....but the more complex it is, the harder it is to read, understand, and modify - and the slower it becomes (e.g. a loop around forking several programs is abysmally slow). At that point, the time/effort cost of writing and maintaining a shell script greatly exceeds the cost of learning the basics ofawk
(orperl
, orpython
) and rewriting it in about 1/10th the lines of codes. If you already know one of those languages, then that point is reached much earlier. -
Georgi Stoyanov over 6 yearsI am writing a script to emulate network impairments using iproute and tc command. I was using this array approach to check if the user defined variable is valid. I believe writing this script in python would be a bit painful and I am also using the opportunity to learn a bit of bash.
-
-
Georgi Stoyanov over 6 yearshow can I exclude the
lo
localhost interface from the array? -
Kevin Lemaire over 6 yearsadded in answer and question
-
Georgi Stoyanov over 6 yearsActually you can do the same just by removing the last item in the array, I have found the answer in the meantime:
unset "net_array[${#net_array[@]}-1]"
-
Kevin Lemaire over 6 yearsI won't do that because I'm not sure localhost will always be in last position
-
lgekman over 4 yearsTypo; shall be "ip -j link show"