0

I have been writing a script which will run in while loop infinite times

If all condition are met then only the script will break and execute another command

My code :

while true
do 
   
   # Note : below field will execute some command and generate value   
   field1=`some command which gives status`
   field2=`some command which gives status`
   field3=`some command which gives status`
   field4=`some command which gives status`

   if [ "$field1" == "A" ] &&  [ "$field2" == "A" ] && [ "$field3" == "A" ] && [ "$field4" == "A" ] 
   then
         break
   else
         echo "Conditions are not met !!!" 
   fi 
done

echo "Another command execution started ... "

The issue here is the number of fields might vary

Need to make my script generic and incase I have 10 fields also it should frame a

if condition dynamically and start executing until all fields becomes equal to A and break for executing another command

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
kiric8494
  • 195
  • 1
  • 7
  • Likely you want an array instead of a "Variable number of variables". Can you share more about how these "Fields" are being captured? Your `awk` is broken so it's not clear how these values are derived, and likely that's where the work is to solve this. – JNevill May 24 '22 at 15:30
  • @JNevill : Sure let me edit the question with much more details – kiric8494 May 24 '22 at 15:32
  • Have you considered making just one `field` array? If you have `field[1]`, `field[2]`, `field[3]` etc. as array elements, iterating over them is trivial. – Charles Duffy May 24 '22 at 18:46

4 Answers4

1

Assuming all "success" return status is A, is a single character length.

We can aggregate all return status code into a long string. Than try to search for a non A value.

local ret_val=""
while true; do 
   
   # Note : below field will execute some command and generate value   
   ret_val="${ret_val}$(some command1 which gives status)"
   ret_val="${ret_val}$(some command2 which gives status)"
   ret_val="${ret_val}$(some command3 which gives status)"
   ret_val="${ret_val}$(some command4 which gives status)"

   if [[ ${ret_val} =~ "[^A]*" ]]; then
     echo "Conditions are not met !!!" 
   else
     break
   fi 
done

echo "Another command execution started ... "

If all "success" return status is a multi-digit number.

You can convert the numeric return status to a single character, see in this answer.

Dudi Boy
  • 4,551
  • 1
  • 15
  • 30
1

Something like this? But this only works with single line result

A="A"
output="something to start"
until [ -z "$(echo $output | grep -v $A)" ]
do
    output=$(cat <<EOF
`cat A`  # First command
`cat B`  # Second command
EOF
)
    echo "Waiting for condition"
    sleep 1
done

you could try to

echo "A" > A
echo "B" > B

Stop condition

echo "A" > B
Justin Yu
  • 61
  • 5
1

Using an array for your fields lets you loop over them, and putting it in a function lets you use return to end execution even if inside multiple nested loops:

poll() {
  while true; do 
    declare -a fields=( )
    # Note : below field will execute some command and generate value   
    fields[1]=`some command which gives status`
    fields[2]=`some command which gives status`
    fields[3]=`some command which gives status`
    fields[4]=`some command which gives status`

    any_bad=0
    for field_idx in "${!fields[@]}"; do
      field_val=${fields[$field_idx]}
      if [[ $field_val != "A" ]]; then
        echo "Conditions not met (field $field_idx is not $field_val, not A)" >&2
        any_bad=1
        break
      fi
    done
    (( any_bad == 0 )) && return
  done
}
poll
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
1

So just check for any line other than A.

   res=$(
some command which gives status
some command which gives status
some command which gives status
some command which gives status
)
if <<<"$res" grep -xFqv A; then
     echo "Conditions is not met !!!"
fi
KamilCuk
  • 120,984
  • 8
  • 59
  • 111