LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-25-2012, 05:03 PM   #1
theillien
Member
 
Registered: Jan 2004
Posts: 112

Rep: Reputation: 1
Populate multiple variables via loop


The sitch:
We have a hosted virtual environment (I loathe the term 'cloud') on a VMware core which is poorly implemented. It does a bad job of managing RHEL6 copies simply because it was an old version of ESXi that doesn't support it. As a result, we found little need to install VMware Tools. However, we recently became aware that at some point, copies became possible, but not particularly useful since we still don't have VMware Tools installed on any of our RHEL6 VMs (plus, we still don't know how effective it will be even with VMware Tools installed).

This creates a problem with MAC addresses. When a VM is either copied from one compute pool to another or simply moved to a different VLAN, the MAC changes. Since Tools isn't there to manage the behind the scenes reconfiguration during a copy, we are forced do update the MAC settings ourselves in both the udev rules file as well as the ifcfg files. This is tedious and I'd like to write a script that makes the changes for me.

Let's say I have two interfaces: eth0 and eth1. When I make a copy, rather than updating those two interfaces with new MACs, the udev file creates two new entries with the new MACs and names them eth2 and eth4. I then have to go in, either delete or comment out the eth0 and eth1 then edit the two new lines to be eth0 and eth1 instead.

I then have to take those new MACs and enter them into the ifcfg files and then reboot the VM so the networking subsystem associates the new hardware with eth0 and eth1 correctly.

What I have so far:
I can extract each MAC using grep and awk
Code:
# MAC=$(grep eth0 /etc/udev/rules.d/70-persistent-net.rules |awk -F, '{print $4}' |awk -F== '{print $2}')
I can then echo $MAC and get the result I expect:
Code:
# echo $MAC
"00:50:56:88:1c:77"
However, I have to run this individually for each interface assigning to a new variable each time. The quotes are expected and actually needed since RHEL6 now uses them in the ifcfg files.

What I want to do:
For starters, what I want to do is, for each MAC in the file, assign it to a different variable. eth0 to $MAC0, eth1 to $MAC1 etc

I tried using a for loop, but that didn't work:
Code:
# for i in {0..4}; do MAC$i=$(grep eth$i \
/etc/udev/rules.d/70-persistent-net.rules \
|awk -F, '{print $4}' |awk -F== '{print $2}'); done
That results in
Code:
-bash: MAC0="00:50:88:1c:77": command not found
-bash: MAC1="00:50:88:1c:78": command not found
-bash: MAC2="00:50:88:1c:79": command not found
-bash: MAC3="00:50:88:1c:80": command not found
The real questions:
A: a: Why is it trying to execute the variables as if they were commands? b: Does it have to do with the quotes?

B: a: How can I accomplish what I'm trying to do? b: If the quotes are an issue, how should I go about dealing with them?
 
Old 05-25-2012, 05:16 PM   #2
masavini
Member
 
Registered: Jun 2008
Posts: 285

Rep: Reputation: 6
hi,
this code works fine for me:

Code:
for i in {0..4}; do 
MAC[$i]=$(grep "eth$i" /etc/udev/rules.d/70-persistent-net.rules | awk -F ',' '{print $4}' | awk -F '==' '{print $2}')
echo ${MAC[$i]}
done
if you want to remove quotes, just pipe sed 's/"//g' in the end of the 2nd line:

Code:
for i in {0..4}; do 
MAC[$i]=$(grep "eth$i" /etc/udev/rules.d/70-persistent-net.rules | awk -F ',' '{print $4}' | awk -F '==' '{print $2}' | 's/"//g')
echo ${MAC[$i]}
done
 
Old 05-25-2012, 06:19 PM   #3
theillien
Member
 
Registered: Jan 2004
Posts: 112

Original Poster
Rep: Reputation: 1
Thank you. This is starting to take shape now. I do need more help, though. Now I have this:
Code:
#!/bin/bash -x

for i in {0..5}
do
    MAC[$i]=$(grep eth$i /etc/udev/rules.d/70-persistent-net.rules |awk -F ',' '{print $4}' |awk -F '==' '{print $2}')

    if [ $i -lt 3 ]
    then
    # Commented out for debugging
    #    sed -i "/eth$i/ s/^/#/" /etc/udev/rules.d/70-persistent-net.rules
    echo "null" # So there are no errors with the if block having empty sections
    else
        subInt=$(echo $i |awk '{print ($1 - 3)}'
        echo $subInt #debugging
    fi
done
$subInt is not being populated because $1 shows as null. How can I get the value of $subInt to be the result of the math I'm trying to execute?

Last edited by theillien; 05-25-2012 at 06:22 PM. Reason: forgot a line in the if block
 
Old 05-25-2012, 09:38 PM   #4
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
There's no closing ")" after "subInt=$("
 
Old 05-25-2012, 09:56 PM   #5
theillien
Member
 
Registered: Jan 2004
Posts: 112

Original Poster
Rep: Reputation: 1
Well, yes, that would certainly be an issue. I assure you, though, that it was simply lost in the transcription. In the script it is in place.
 
Old 05-25-2012, 10:07 PM   #6
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by theillien View Post
Well, yes, that would certainly be an issue. I assure you, though, that it was simply lost in the transcription. In the script it is in place.
If you can copy and paste it would avoid such problems.

Can you post your /etc/udev/rules.d/70-persistent-net.rules? I've tried the script with my one line 70-persistent-net.rules but it didn't help.
 
Old 05-25-2012, 10:24 PM   #7
theillien
Member
 
Registered: Jan 2004
Posts: 112

Original Poster
Rep: Reputation: 1
I couldn't copy/paste. I was working with a console window as opposed to a terminal.

The contents of the file are irrelevant. The issue is that when I pipe the value of the variable to awk using the echo $i command it is null. There is no value being stored in $1.
 
Old 05-25-2012, 11:06 PM   #8
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by theillien View Post
The issue is that when I pipe the value of the variable to awk using the echo $i command it is null. There is no value being stored in $1.
What is the evidence for that? Testing at the command prompt it works for me:
Code:
c@CW8:/tmp$ cat script.sh 
#!/bin/bash

i=1
echo $i | awk '{print "DEBUG: $1: " $1}'
subInt=$(echo $i | awk '{print ($1 - 3)}' )
echo "DEBUG: subInt: $subInt"
c@CW8:/tmp$ ./script.sh 
DEBUG: $1: 1
DEBUG: subInt: -2
 
Old 05-26-2012, 12:04 PM   #9
theillien
Member
 
Registered: Jan 2004
Posts: 112

Original Poster
Rep: Reputation: 1
I figured out the problem. I was using double quotes around the awk print statement. I've corrected them to be single-quotes.

When I run it now, I get the results I'm expecting.

Last edited by theillien; 05-26-2012 at 12:07 PM.
 
Old 05-27-2012, 04:36 AM   #10
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
For the record, your trouble came from your attempt to create variable variables, which you nearly always can, and should, avoid doing. This kind of thing can nearly always be handled better with an array of some type. See here:

How can I use variable variables (indirect variables, pointers, references) or associative arrays?
http://mywiki.wooledge.org/BashFAQ/006
 
Old 05-27-2012, 08:33 AM   #11
theillien
Member
 
Registered: Jan 2004
Posts: 112

Original Poster
Rep: Reputation: 1
No, the trouble came from the double quotes. Thanks for the input, though.
 
Old 05-27-2012, 08:50 AM   #12
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
The trouble that lead to you making your initial post came from trying to use variable variables. That's what my post and link were referring to. I posted it so you, and anyone else who comes across this thread later, could learn the concept behind the solution, rather than just the quick code fix.
 
Old 05-27-2012, 09:00 AM   #13
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
I am a little late to this party but not sure what the subint thing was about. As for the original question of card addresses, why not just use:
Code:
MAC=( $(awk -F\" '/eth/{print $8) )
Now you have an array with each MAC address.

Also, for what I did understand as the transaction required for subint is to take away 3:
Code:
(( i -= 3 ))
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
how can we use multiple variables in single for loop in shell script nagendrar Linux - Newbie 11 05-22-2017 01:21 PM
Loop with variables sebastiaankop Linux - Newbie 2 01-06-2011 08:35 AM
Loop with 2 variables tensigh Programming 7 11-17-2009 07:07 PM
Why does this loop clear variables? novaraz Programming 6 10-25-2008 08:40 AM
Using for loop on 2 variables muazfarooqaslam Linux - Newbie 8 02-01-2008 08:03 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:08 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration