'Bash: how to evaluate results of commands inside double brackets
I guess mytrue
and myfalse
are considered strings instead of commands:
myfalse () {
return 0
}
mytrue () {
return 1
}
test-conditional ( ) {
SHOW="dont-show"
[[ ${SHOW} == "show" || mytrue ]] && echo "ok" || echo "wrong"
[[ ${SHOW} == "show" && mytrue ]] && echo "err" || echo "ok"
[[ ${SHOW} == "show" || myfalse ]] && echo "err" || echo "ok"
[[ ${SHOW} == "show" && myfalse ]] && echo "err" || echo "ok"
SHOW="show"
[[ ${SHOW} == "show" || mytrue ]] && echo "ok" || echo "err"
[[ ${SHOW} == "show" && mytrue ]] && echo "ok" || echo "err"
[[ ${SHOW} == "show" || myfalse ]] && echo "ok" || echo "err"
[[ ${SHOW} == "show" && mytrue ]] && echo "err" || echo "ok"
}
test-conditional
So this is showing wrong output:
ok
ok
err
ok
ok
ok
ok
err
(It should be ok
everywhere)
How can evaluate commands inside double brackets?
Solution 1:[1]
You have true
and false
functions returning opposite return codes and your last condition needs a correction.
You can use:
myfalse () {
return 1
}
mytrue () {
return 0
}
test-conditional ( ) {
SHOW="dont-show"
[[ ${SHOW} == "show" ]] || mytrue && echo "ok" || echo "wrong"
[[ ${SHOW} == "show" ]] && mytrue && echo "err" || echo "ok"
[[ ${SHOW} == "show" ]] || myfalse && echo "err" || echo "ok"
[[ ${SHOW} == "show" ]] && myfalse && echo "err" || echo "ok"
SHOW="show"
[[ ${SHOW} == "show" ]] || mytrue && echo "ok" || echo "err"
[[ ${SHOW} == "show" ]] && mytrue && echo "ok" || echo "err"
[[ ${SHOW} == "show" ]] || myfalse && echo "ok" || echo "err"
[[ ${SHOW} == "show" ]] && myfalse && echo "err" || echo "ok"
}
test-conditional
Also note how function call is placed outside [[ ... ]]
otherwise it won't invoke function.
Following rules apply while evaluating these expressions:
- Condition after
&&
isn't evaluated if first condition fails. - Condition after
||
isn't evaluated if first condition succeeds.
Solution 2:[2]
Inside a bash [[…]]
(and inside the older […]
in most shells) what matters is if the value tested has some characters or not:
$ [[ somevalue ]] && echo "yes" || echo "no"
If the value tested if empty, the test fails:
$ [[ "" ]] && echo "yes" || echo "no"
no
That is also true for variables:
$ somevalue="a false string"
$ [[ $somevalue ]] && echo "yes" || echo "no"
yes
$ somevalue=""
$ [[ $somevalue ]] && echo "yes" || echo "no"
no
So, [[…]]
is limited to testing strings not "exit codes".
Your functions define "exit codes" not strings.
You may
define the values of
mytrue
andmyfalse
to be variables that represent those values:mytrue=A_True_Value myfalse=""
And use them:
$ show="dont-show" $ [[ ${SHOW} == "show" || $mytrue ]] && echo "ok" || echo "wrong" ok $ [[ ${SHOW} == "show" || $myfalse ]] && echo "ok" || echo "wrong" wrong
Or, actually test exit codes outside a
[[…]]
idiom:$ mytrue(){ return 0; } $ if mytrue; then echo "ok"; else echo "wrong"; fi ok $ mytrue && echo "ok" || echo "wrong" ok
One (more complex) alternative is to make the functions emit a value and call the execution of the code in the functions from the
[[…]]
idiom:$ mytrue(){ echo "A_True_Value"; } $ myfalse(){ echo ""; } $ show="dont-show" $ [[ ${SHOW} == "show" || $(mytrue) ]] && echo "ok" || echo "wrong" ok
KISS
But (probably) the simplest of solutions is the best solution:
myfalse=""
mytrue="true"
test-conditional () {
show="dont-show"
[[ ${show} == "show" || $mytrue ]] && echo "ok" || echo "wrong"
[[ ${show} == "show" && $mytrue ]] && echo "err" || echo "ok"
[[ ${show} == "show" || $myfalse ]] && echo "err" || echo "ok"
[[ ${show} == "show" && $myfalse ]] && echo "err" || echo "ok"
show="show"
[[ ${show} == "show" || $mytrue ]] && echo "ok" || echo "err"
[[ ${show} == "show" && $mytrue ]] && echo "ok" || echo "err"
[[ ${show} == "show" || $myfalse ]] && echo "ok" || echo "err"
[[ ${show} == "show" && $myfalse ]] && echo "err" || echo "ok"
}
test-conditional
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | done |