LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Bash Variable Naming Question? (https://www.linuxquestions.org/questions/linux-newbie-8/bash-variable-naming-question-811170/)

Speedy2k 05-30-2010 08:28 PM

Bash Variable Naming Question?
 
I'm writing a script for asterisk to monitor trunk failure, i do a loop for every trunk it got nad would like to name variable like server1=, server2= naming the server upgoing as the trunk is. here is the scripts:

Code:

#!/bin/bash
#Checking number of SIP Registered trunk.
nmb_sip=`/usr/sbin/asterisk -rx "sip show registry" | gawk -F" " 'FNR>1' | wc -l`
sip_trunk=`/usr/sbin/asterisk -rx "sip show registry" | gawk -F" " 'FNR>1'`
echo Number of SIP Trunk: $nmb_sip
COUNT=1 # counting lines from 1
echo "$sip_trunk" | while read line
do
serveur=`echo $line | gawk -F" " '{print $1}' | gawk -F":" '{print $1}'`
username=`echo $line | gawk -F" " '{print $2}'`
status=`echo $line | gawk -F" " '{print $4}'`
echo Serveur: $serveur
echo Username: $username
echo Status: $status
let COUNT=$COUNT+1
if [[ $COUNT -ge $nmb_sip ]]
        then
                break
fi
done

#Checking number of IAX2 Registered trunk.
nmb_iax2=`/usr/sbin/asterisk -rx "iax2 show registry" | gawk -F" " 'FNR>1' | wc -l`
iax2_trunk=`/usr/sbin/asterisk -rx "iax2 show registry" | gawk -F" " 'FNR>1'`
echo Number of IAX2 Trunk: $nmb_iax2
COUNT="1" # counting lines from 1
echo "$iax2_trunk" | while read line
do
A=$(echo ${line} | gawk -F" " '{print ($1)}' | gawk -F":" '{print ($1)}')
echo $A
server"${COUNT}"="$A"
username=`echo $line | gawk -F" " '{print $3}'`
status=`echo $line | gawk -F" " '{print $6}'`
echo Serveur$COUNT: "$serveur"
echo Username: "$username"
echo Status: "$status"
let COUNT=$COUNT+1
if [[ $COUNT -ge $nmb_iax2 ]]
        then
                break
fi
done

what i would like to do is name the variable server, username and status with the count variable, like this server$COUNT to have server1 when on trunk one, bu as soon as i add the $COUNT after the server, it seems to try to make it a command, it says that:
Code:

./test.sh: line 45: server1=74.63.41.218: command not found
Can someone help me on this one? Thanx!

David the H. 05-30-2010 11:07 PM

Code:

server"$COUNT"="$A"
This is no good. You can't directly use a variable to set the name of another variable, it needs to be a simple string. While there are ways to work around it using eval or indirect referencing to generate dynamic variables, an easier method may be to use an array instead.

Code:

server[$COUNT]="$A"
echo "${server[$COUNT]}"

Note that for bash v.3 or earlier, the $COUNT index must be an integer, but bash v.4 has associative arrays, which allow strings to be used.

BTW: I see two different spellings, server, and serveur. Are these supposed to be the same? Also, you should quote your echo strings.
Code:

echo "Serveur: $serveur"
Finally, $(...) is recommended over `...`.

grail 05-31-2010 03:28 AM

ok ... while not easy it is actually possible to have dynamic variables but its fiddly and you may need to be careful on how you go about it.
The general scenario is this:

1. Create variable names using eval
2. Assign the created variable name to another variable
3. Access data using indirect references
Code:

#!/bin/bash

n=12

eval $(echo "var$n=ten")
vars="var$n"

echo $var12 # this is just to show you that using the full name works.
echo ${!vars}


Speedy2k 05-31-2010 04:01 PM

Code:

Code:
server[$COUNT]="$A"
echo "${server[$COUNT]}"

This as worked perfeclty thanx a lot, but here is another problem i got:

Code:

#Checking number if IAX2 Peer marked as trunk.
nmb_iax2_peer=`/usr/sbin/asterisk -rx "iax2 show peers" | grep " (T) " | wc -l`
iax2_peer=`/usr/sbin/asterisk -rx "iax2 show peers" | grep " (T) "`
echo ""
echo "Number of IAX2 Peers marked as trunk: $nmb_iax2_peer"
COUNT="1" # counting lines from 1
echo "$iax2_peer" | while read line
do
IAXPEERSRV[$COUNT]=$(echo ${line} | gawk -F" " '{print $2}')
IAXPEERUSER[$COUNT]=$(echo ${line} | gawk -F" " '{print ($1)}' | gawk -F"/" '{print ($1)}')
IAXPEERSTAT[$COUNT]=$(echo ${line} | gawk -F" " '{print $7}')
echo "*****IAX2 Peer ${COUNT} Information*****"
echo ""
echo "IAX2 Peer ${COUNT} Server: ${IAXPEERSRV[$COUNT]}"
echo "IAX2 Peer ${COUNT} Username: ${IAXPEERUSER[$COUNT]}"
echo "IAX2 Peer ${COUNT} Status: ${IAXPEERSTAT[$COUNT]}"
if [[ ${IAXPEERSTAT[$COUNT]} == "OK" ]]
        then
                echo "All is perfect for this one."
        else
                echo "Something wrong"
                iax_reload="1"
               
fi

let COUNT=$COUNT+1
if [[ $COUNT > $nmb_iax2_peer ]]
        then
                echo "*****End IAX2 Peers INFORMATION*****"
fi
done
echo "${sip_reload}"
echo "${iax_reload}"
if [[ $sip_reload == "1" ]]
        then
                echo "We are gona reload the SIP module to make those trunk come back online."
                /usr/sbin/asterisk -rx "module reload dnsmgr"
                /usr/sbin/asterisk -rx "module reload chan_sip.so"
                break
fi
if [[ $iax_reload == "1" ]]
        then
                echo "We are gona reload the IAX2 module to make those trunk come back online."
                /usr/sbin/asterisk -rx "module reload dnsmgr"
                /usr/sbin/asterisk -rx "module reload chan_iax2.so"
                break
fi

The problem i got you can see at the end is the iax_reload variable doesn't seems to be exported out of the while loop?? Is there anyway to do that ?? Thanx!

grail 05-31-2010 06:25 PM

That is because you used a pipe into the loop. This cause a subshell and once returned from any variables created inside are lost.
Dpepnding on what is stored in iax2_peer you could try a for in loop or maybe a here document on your while loop

David the H. 05-31-2010 11:22 PM

You can also use a here string instead of a pipe.

Code:

while read line; do
    stuff       
done <<<"$iax2_peer"


grail 06-01-2010 12:14 AM

Damn ... string not document ... that was what I was thinking of .. thanks David :0

David the H. 06-01-2010 08:23 AM

Actually, it is possible to use a here document as well. It's just not as clean looking ;)
Code:

while read line; do
    stuff       
done <<FOO
$iax2_peer
FOO



All times are GMT -5. The time now is 04:29 PM.