0

I usually check if a command succeeds or time out like this, which works just fine;

if timeout 30 someCommand; then
    echo "we're good"
else
    echo "command either failed or timed out"
fi

But with my new script which works with loops and variables, this simply doesn't work as expected;

wallets=/usr/local/bin/*-cli

for i in $wallets; do
    current_blocks=$(timeout 30 $i getblockcount)

    if $current_blocks; then
        echo "we're good"
    else
        echo "command either failed or timed out"
    fi
done

how can I fix this?

3
  • with $( ..) you are storing the output to some variable not the return code Commented Feb 20, 2019 at 17:19
  • Immediately after current_blocks=$(timeout 30 $i getblockcount) you can do currentBlocksRetCode=$? to get the return code, then if [[ $currentBlocksRetcode -eq 0 ]] then you are good. Commented Feb 20, 2019 at 17:19
  • @PS. I thought it's the same as putting the command between code quotes. @marekful this way it always returns we're good even if the command fails or time outs. Commented Feb 20, 2019 at 17:22

2 Answers 2

2

The status of the previous command is available as $?:

wallets=/usr/local/bin/*-cli

for i in $wallets; do
    current_blocks=$(timeout 30 "$i" getblockcount)
    status=$?

    if [ "$status" -eq 0 ]; then
        echo "we're good"
    else
        echo "command either failed or timed out"
    fi
done

Or you can check the status directly:

if current_blocks=$(timeout 30 "$i" getblockcount)
then
  echo "It's good and the result is $current_blocks"
fi
Sign up to request clarification or add additional context in comments.

1 Comment

Never mind, my mistake. I’d put quotes around the subshell invocations but they are not required.
1

Assuming that the normal result of $(timeout 30 $i getblockcount) is a bunch of JSON, you'll need to use more quotes in order to capture the string and then test it for non-emptiness.

The code fragment should look something like this:

  current_blocks="$(timeout 30 $i getblockcount)"

  if [[ -n "$current_blocks" ]]; then
    echo "we're good"
  else
    echo "Command failed or timed out"
  fi

Alternatively, if you only want to check the return status of the command, you can check the $? variable. However, when using timeout with a command, the result status can be either the command status, or 124 from a timeout. If the command does not manage status returns very well, testing for a consistent status might be challenging -- unless you simply want to test for a zero (success) status.

In which case, the code fragment might look like:

  current_blocks="$(timeout 30 $i getblockcount)"

  if (( $? == 0 )); then
    echo "we're good"
  else
    echo "Command failed or timed out"
  fi

2 Comments

It just returns a number on its own and nothing else.
You'll still need to use [[ -n $current_blocks ]] to test if the value of current_blocks is empty or not. [[ $current_blocks ]] can also work, but relies on the variable value being syntactically "safe".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.