2

is it possible to assign variable inside if conditional in bash 4? ie. in the function below I want to assign output of executing cmd to output and check whether it is an empty string - both inside test conditional. The function should output

"command returned: bar"

myfunc() {

local cmd="echo bar"
local output=

while [[ -z output=`$cmd` ]];
do
    #cmd is failing so far, wait and try again
    sleep 5
done

# great success
echo "command returned: $output"
}

why the above?

i prefer to run scripts with 'set -e' - which will cause script to terminate on first non-0 return/exit code that's not in an if/loop conditional.

with that in mind, imagine cmd is an unstable command that may exit with > 1 from time to time, and I want to keep calling it until it succeeds and i get some output.

5
  • your code is equivalent to if [[ ! -z output=bar ]]. Commented Feb 3, 2012 at 21:22
  • Did you try it? Why do you want to do it in the first place? Commented Feb 3, 2012 at 21:24
  • the above is a trivial example - I will clarify Commented Feb 3, 2012 at 21:26
  • I just rewrote it to make it clear that that is not an assignment.. Commented Feb 3, 2012 at 21:29
  • 1
    @yi_H sorry, don't follow you - i do want to assign value to output and check whether it is an empty string - inside test conditional Commented Feb 3, 2012 at 21:34

4 Answers 4

3

You can try something like this:

myfunc() {

    local cmd="echo bar"
    local output=

    while ! output=$($cmd) || [[ -z output ]];
    do
        #cmd is failing so far, wait and try again
        sleep 5
    done

    # great success
    echo "command returned: $output"
}

Note that it is strongly recommended to avoid the use of set -e.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for the answer - works for me. Too bad about 'set -e' being unreliable - IMO achieving the goal behind set -e would be highly useful
0

I don't think you would be able to do it in your conditional

As yi_H pointed out, the if is equivalent to

if [[ ! -z output=bar ]];

which in turn is basically

if [[ ! -z "output=bar" ]];

So, all you are checking is if the string "output=bar" is empty or not...

So, output=bar could actually be anything like !@#!@%=== and it would still do the same thing (that is, the expression isn't evaluated). You might have to assign the variable in a subshell somehow, but I'm not sure that would work.

Comments

0

Since assignment won't work there, you need some workaroudn.

You could temporary do a set +e...

Comments

-1

You could use this way ...

$cmd
exit_status=$?

while [[ $exit_status -gt 0 ]];
do
    #cmd is failing so far, wait and try again
    sleep 5

    $cmd
    exit_status=$?
done

EDIT: This won't work with 'set -e' or other way around, don't use 'set -e' to begin with.

2 Comments

if 'set -e' is used (see question), and $cmd returns != 0, bash will exit after the very first line
Agreed, and that is why this answer did not include it. 'set -e' causes confusion and forces to write scripts in not natural way. IMO, it is more of a trouble than it is worth. This small piece of code is the very example why it should be avoided.

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.