toast
toast

Reputation: 592

Concatinating variable names in bash script

I am trying to run commands based on the output of a previous command:

ifaces=$(ls /sys/class/net)
for i in "${ifaces[@]}"
do
   mac=$(cat /sys/class/net/$i/address)
   echo "$i: $mac"
done

but its not working, i'm not sure if my method of concatenation is wrong?

Upvotes: 1

Views: 40

Answers (2)

Charles Duffy
Charles Duffy

Reputation: 296049

for i in /sys/class/net/*; do
  mac=$(<"$i/address")
  echo "${i##*/}: $mac"
done
  • ls output is formatted for human readability rather than progammatic use. Because filenames can contain literal newlines, but ls separates names with newlines, it's impossible to both literally represent those names (without escape characters or sequences) and distinguish where on name ends and the next begins. Don't use it programatically.
  • $(<file), unlike $(cat "$file"), doesn't actually need to fork() off a subprocess, or exec() an external executable. Consequently, it's considerably more efficient.
  • ${i##*/} removes the longest string matching the glob expression */ to the variable $i. Consequently, it effectively returns only the filename.

Upvotes: 2

Evya
Evya

Reputation: 2385

When your assigning the output of ls to ifaces, wrap it with an array to successfully iterate over the contents:

ifaces=($(ls /sys/class/net))
for i in "${ifaces[@]}"
do
   mac=$(cat /sys/class/net/$i/address)
   echo "$i: $mac"
done

Upvotes: 0

Related Questions