21

Explanation:

I have a small bash script which simply runs any Linux command (e.g. say ifconfig)

The typical output of ifconfig is something like this:

eth0      Link encap:Ethernet  HWaddr 30:F7:0D:6D:34:CA
          inet addr:10.106.145.12  Bcast:10.106.145.255  Mask:255.255.255.0
          inet6 addr: fe80::32f7:dff:fe6d:34ca/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1104666 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2171 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:444437904 (423.8 MiB)  TX bytes:238380 (232.7 KiB)

lo        Link encap:Local Loopback 
          inet addr:127.0.0.1  Mask:255.255.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:15900 errors:0 dropped:0 overruns:0 frame:0
          TX packets:15900 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:467306 (456.3 KiB)  TX bytes:467306 (456.3 KiB)

Now what most people usually do is store the entire output into a file/variable and parse based on that. I however want to know if there is anyway that I could put specific parts of the output in more than one variable (say a bash variable called ${IPETH0} to carry the IP address 10.106.145.12 from eth0 and ${IPLO} to carry the IP address 127.0.0.1 from lo in the above example without running ifconfig command twice).

Something like what tee command does with the input but I want to do this for the output and store the output into 2 or more variables in one go. Any ideas?

user000001
  • 32,226
  • 12
  • 81
  • 108
Arpith
  • 570
  • 2
  • 10
  • 26
  • Unless you run your script with `source`, you cannot set variables in the calling environment. See http://stackoverflow.com/questions/496702/can-a-shell-script-set-environment-variables-of-the-calling-shell – user123444555621 Aug 26 '13 at 18:35
  • @Pumbaa80: I did not quite think so far as the exporting of the variables. Thanks for that tidbit nevertheless. :-) – Arpith Aug 26 '13 at 18:46

3 Answers3

18
$ read IPETH0 IPLO <<< $(ifconfig | awk '/inet[[:space:]]/ { print $2 }')
$ echo "${IPETH0}"
192.168.23.2
$ echo "${IPLO}"
127.0.0.1

This assumes the order of the eth0 and lo interfaces, but it shows the basic idea.

Adrian Frühwirth
  • 42,970
  • 10
  • 60
  • 71
  • 1
    How do I change the delimiters? This is what I got: $echo ${IPETH0} addr:10.106.145.12 $echo ${IPLO} addr:127.0.0.1 – Arpith Aug 26 '13 at 18:30
  • 1
    @Arpith: My `ifconfig` output does not include the address family, my mistake...you can try `read IPETH0 IPLO <<< $(ifconfig | awk -F'[[:space:]:]+' '/inet[^6]/ { print $3 }')` to include the colon as a delimiter. – Adrian Frühwirth Aug 26 '13 at 18:38
  • Went ahead and used cut. Exactly what I was looking for. Great answer! Thank you. (Note to self: I seriously need to learn awk.) – Arpith Aug 26 '13 at 18:41
  • 1
    Whatever works for you :-) But yes, `awk` is great...just read a few of e.g. [@EdMorton's](http://stackoverflow.com/users/1745001/ed-morton) answers and you will soon know most things you will need ;-) – Adrian Frühwirth Aug 26 '13 at 18:45
  • 1
    plus 1, for multi-variable assignment oneliner – Evhz Aug 23 '18 at 10:00
4

You can use awk and bash arrays:

arr=( $(awk -F ':' '$1 == "inet addr"{sub(/ .*/, "", $2); print $2}' < <(ifconfig)) )

Then you can do:

read IPETH0 IPLO <<< ${arr[@]}
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    This creates a numeric-index array, but doesn't link the IPs to the interface names. – Barmar Aug 26 '13 at 18:21
  • @Barmar: Agreed, associative arrays are latest edition to newer versions of BASH only. Unfortunately I am on OSX and still on older BASH. However shell variables can be created from this array (as in my edit) – anubhava Aug 26 '13 at 18:24
3

you can read each line of ifconfig and set variables :

while read l1 ;do 
   if [[ $l1 =~ inet ]];then     
      set -- $l1 
      echo  "ip is  $2  " 

   fi
done < <(ifconfig)
michael501
  • 1,452
  • 9
  • 18
  • 1
    This keeps setting the same variables each time through the loop, so it won't set different variables for each interface. – Barmar Aug 26 '13 at 18:28