Search code examples
bashwhile-loopsh

While loop bash to check command rv


Im having issues with checking the return values of two commands in the conditional statement of a while loop in bash.

I have the following code:

set e+
while ! array1=(‘getSensorValues 1’) && array2=(‘getSensorValues 2’);
do 
  echo “failed to get sensor values, retrying” 
  sleep 0.1 
done 
echo “array 1: ${array1[*]}”
echo “array 2: ${array2[*]}”
set e- 

The function getSensorValues works and returns an array of values. It checks values that are being populated in real time. It will return 1 if the file it queries is locked by another process. So in the case where either of these functions return 1 , I want to retry in 100ms. I did this before by running each separately and getting their rv and just retrying if either are 1 but I want to do this in the least number of lines possible.

The code above does not work as the array2 variable does not get set, so the second command seems to not execute, I’m assuming because the first one passes.

Please, any help greatly appreciated.


Solution

  • Try this Shellcheck-clean code:

    #! /bin/bash -p
    
    while ! gsv1=$(getSensorValues 1) || ! gsv2=$(getSensorValues 2); do
        echo 'failed to get sensor values, retrying' >&2
        sleep 0.1
    done
    
    read -r -a array1 <<<"$gsv1"
    read -r -a array2 <<<"$gsv2"
    
    declare -p array1 array2
    
    • I've dropped the (corrected) set +e and set -e because the functions are run in a loop guard so non-zero returns will not trigger errexit.
    • The while loop guard depends on the fact that ! { test1 && test2; } is equivalent to ! test1 || ! test2 (one of De Morgan's laws).
    • Shellcheck correctly complains about array1=( $(getSensorValues 1) ) and similar (SC2207), so I've replaced the array assignment with a simple string assignment. The string is then safely split into an array using read -r -a ....
    • I've added >&2 to the echo command because diagnostic output should go to standard error.