1

I'm new to bash and try a simple loop but the value of my variable is being lost after it and I can not understand why - I have looked at few similar issues but they are all related to subshell execution of a while loop . I'm not doing but still facing issues - can someone explain me where is my mistake ?

#!/bin/bash

check_ss ()    
{    

command_list | awk '{print $1 $9}' > ss.out    

 for i in {1..8}    
            do grep -Pa "\x3$i" ss.out > ss$i.out   
                    if grep -w "NotStarted" ss$i.out   
                            then   
                                   ss$i=0   
                            else    
                                ss$i=1    
                    fi   
done   
}   
check_ss      
echo $ss1     
echo $ss2    
echo $ss3    
echo $ss4    

I'm getting this on execution :

[root@lubo ~]# ./ss.sh    
./ss.sh: line 21: ss1=1: command not found     
./ss.sh: line 21: ss2=1: command not found      
./ss.sh: line 21: ss3=1: command not found      
./ss.sh: line 21: ss4=1: command not found      
./ss.sh: line 21: ss5=1: command not found      
./ss.sh: line 21: ss6=1: command not found     
./ss.sh: line 21: ss7=1: command not found     
./ss.sh: line 21: ss8=1: command not found   

Thanks in advance

2 Answers 2

5

You need to use declare to dynamically construct a variable name.

declare "ss$i=0"
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks , this somehow changed the situation , but the script is still trying to execute ss1=1 as a command instead assinging a value to a variable ss1 : ./ss.sh: line 11: ss1=0: command not found ./ss.sh: line 17: ss1=1: command not found
Those error messages indicate you aren't using declare on those lines. A simple assignment must have a literal word as the LHS; any parameter expansions require the declare command.
Thanks , I did it with declare - now the command not found are not appearing anymore but when doing echo $ss1 , echo $ss2 the output is empty , it seems the variable value is lost somewhere
2

An array would be a better alternative to dynamic variable names.

check_ss() {
    ss=()
    command_list | awk '{print $1 $9}' > ss.out

    for i in {1..8}; do
        grep -Pa "\x3$i" ss.out > ss$i.out
        if grep -w "NotStarted" ss$i.out; then
            ss[$i]=0
        else
            ss[$i]=1
        fi
    done
}

check_ss      
echo ${ss[1]}
echo ${ss[2]}
echo ${ss[3]}
echo ${ss[4]}

You could also get rid of the temporary files.

check_ss() {
    ss=()
    command_list | awk '{print $1 $9}' > ss.out

    for i in {1..8}; do
        if grep -Pa "\x3$i" ss.out | grep -w "NotStarted"; then
            ss[$i]=0
        else
            ss[$i]=1
        fi
    done
}

I don't know what your input looks like exactly, but you might even be able to simplify it further to something like:

check_ss() {
    ss=()
    while read i; do
        ss[$i]=1
    done < <(command_list | awk '$9=="NotStarted" {print $1}')
}

or if you just want a list of the NotStarted numbers,

ss=(command_list | awk '$9=="NotStarted" {print $1}')
echo "${ss[@]}"

2 Comments

Thanks a lot for the quick answer , I'm trying to do the following to parse a text file which will containing a status of a service - either NotStarted or Else (Running , Initializing , Fault , etc. ) Here is the output of your proposal : [root@hp44fd96d3f8-2 ~]# cat ss1.out 1Initialising [root@hp44fd96d3f8-2 ~]# cat ss2.out 2NotStarted [root@hp44fd96d3f8-2 ~]# ./ss.sh 1 1 1 1 [root@hp44fd96d3f8-2 ~]#
Sorry for the formatting , not sure how to select the code or go to a new line when answering, anyway - i want to give every ss$i a value 1 = NotStarted or 0 = Running. For example ss1=1 , ss2 = 1 , ss3 = 0 , ss4 =1 and so on

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.