i have the following code
elif [ $text2 == 'LANDING' ] && [ "$text4" == 'FAIL' ] || [ "$text4" == '' ]; then
the condition is that text2 should be landing and text4 can either be fail or null.
How to evaluate the above command.
Please help if Im doing any wrong
Thanks in advance
You need to group them explicitly:
elif [ "$text2" = 'LANDING' ] &&
{ [ "$text4" = 'FAIL' ] || [ "$text4" = '' ]; }; then
Your attempt would succeed either of the following two conditions held:
text2 was LANDING and text4 was FAIL
text4 was empty or unset.
Since && and || have the same precedence, you could (perhaps surprisingly) write it without grouping:
elif [ "$text4" = '' ] || [ "$text4" = FAIL ] && [ $text2 == 'LANDING' ]; then
If you are using bash, you can use the [[ ... ]] command instead of [ ... ]. The grouping is required; the operators inside [[ ... ]] do have the precedences you would expect from other languages (that is, a || b && c is a || (b && c), not (a || b) && c).
elif [[ $text2 == 'LANDING' && ( "$text4" == 'FAIL' || "$text4" == '') ]]; then
Not particular recommended, but with bash, you can use extended globbing patterns in [[...]]
elif [[ $text2 == 'LANDING' && $text4 == #(FAIL|) ]]; then
Use curly braces or parentheses to group the || operands together. Parentheses look nicer, but they create a subshell which is inefficient, so curly braces are the way to go even though they're ugly.
elif [ $text2 == 'LANDING' ] && { [ "$text4" == 'FAIL' ] || [ "$text4" == '' ]; }; then
Notice that the curly braces require an extra semicolon.
Alternatively, if you're using bash you could use double square brackets, which allow for the slightly prettier:
elif [[ $text2 == 'LANDING' && ("$text4" == 'FAIL' || "$text4" == '') ]]; then
Related
I'm trying to be smart but it doesn't work. Can anybody help me to do this a bit simpler?
if [[ "${DATUM}" == "${today}" && "${STUNDE}" == "${HH24}" ]] || [[ "${DATUM}" == "${today}" && "${STUNDE}" == "20" ]] ||
[[ "${DATUM}" == "${today}" && "${STUNDE}" == "" && "20" == "${HH24}" ]]; then
Is there a way to combine it?
Your code can be translated to:
(C1 and C2) or (C1 and C3) or (C1 and C4 and C5)
Applying boolean arithmetics you can simplify it as:
C1 and (C2 or C3 or (C4 and C5))
This said, you can add a nested if statement to, first, check the C1 condition and, second, check the other conditions. It does not simplify the code a lot but here it is:
if [ "${DATUM}" = "${today}" ]; then
if [ "${STUNDE}" = "${HH24}" ] || [ "${STUNDE}" = "20" ] || { [ "${STUNDE}" = "" ] && [ "${HH24}" = "20" ]; }; then
# Insert the code to execute when the conditions are satisfied
fi
fi
As others have noted, your boolean expression can be simplified applying the law of distributivity of conjunction (⋀, *, AND) over disjunction (⋁, +, OR):
(a ⋀ b) ⋁ (a ⋀ c) = a ⋀ (b ⋁ c)
But to simplify it further, note you can, in bash, use && and || inside the (bash-specific) [[ .. ]] command:
[[ $a == 1 && $b == 2 ]]
Also, when using [[ .. ]] compound command (over POSIX [ .. ]) you don't have to quote variables. And to test for null-strings, you can use the shorter -z $var form over $var == "".
All this together yields:
if [[ $DATUM == $today ]] && [[ $STUNDE == $HH24 || $STUNDE == 20 || -z $STUNDE && $HH24 == 20 ]]; then
# ...
fi
To further simplify it, we would need to have more details on your application logic, possible values, etc.
What I want is
if((TRAVIS_BRANCH != "master") || (TRAVIS_BRANCH == "master" && TRAVIS_PULL_REQUEST == true)
How do I do this in bash? I think this is the closest, but it still doesn't work
if [ "$TRAVIS_BRANCH" != "master" ] || ["$TRAVIS_BRANCH" == "master" && "$TRAVIS_PULL_REQUEST" == "true"]
Make sure the [ and ] characters are surrounded by spaces
Double equals works in Bash, but is not POSIX compatible
You have to use -a, not &&, inside [
Because of the difficulty in working out the precedence rules in shell code it's recommended not to use more than one boolean operator per line of code
It's recommended to use [[ rather than [ in Bash
Result:
is_master_pull_request() {
[[ "$TRAVIS_BRANCH" = "master" ]] && [[ "$TRAVIS_PULL_REQUEST" = "true" ]]
}
if [[ "$TRAVIS_BRANCH" != "master" ]] || is_master_pull_request
Put spaces around your command names ([ is a command name), don't try to use && or || within a single [ command.
if [ "$TRAVIS_BRANCH" != "master" ] || { [ "$TRAVIS_BRANCH" = "master" ] && [ "$TRAVIS_PULL_REQUEST" = "true"]; }
However, you can use && or || inside of [[ ]], and also have less need to quote there:
if [[ $TRAVIS_BRANCH != master ]] || [[ $TRAVIS_BRANCH = master && $TRAVIS_PULL_REQUEST = true ]]
try:
if [ "$TRAVIS_BRANCH" != "master" ] || [[ "$TRAVIS_BRANCH" == "master" && "$TRAVIS_PULL_REQUEST" == "true" ]]; then
I have a shellscript that tells me missing ] in the line
if [ $status != "2" && $status != "3" && `echo "$temp1 > $upperLimit" | bc` = "1" ]
and also missing ] in the line
if [ $status = "2" && `cat motionsensordate` \> `date +%s` ]
Why is that?
The single [ doesn't support logical operators inside the brackets. You have to use them outside
if [ "$status" != 2 ] && [ "$status" != 3 ] ...
Use double quotes for variables in single brackets to prevent unary operator expected error when the variable is empty.
Or, switch to double brackets:
if [[ $status != 2 && $status != 3 ... ]]
Also, status different to 2 and 3 can be expressed by a pattern:
if [[ $status != [23] && ... ]]
And if you would like to (in addition to the answers here) group together conditions:
if [[ ( COND1 || COND2 ) && COND3 ]]
then
echo "$cmd"
break
fi
I'm trying to check if both conditions return the expected values.
I want to be sure that both return the expected value before continuing...
My problematic line is: if [ [ $ansmob = "y" ] || [ $flagbook != "1" ] ];
read -r -p "Would you like to add $site.booking.local as well? [y/n] " ansbook
if [ $ansbook = "y" ];
then sed "s/ServerAlias.*/& $site.booking.local/" -i $workdir/$site$dom.conf
flagbook="1"
fi
read -r -p "Would you like to add m.$site.booking.local? [y/n] " ansmob
if [ [ $ansmob = "y" ] || [ $flagbook != "1" ] ];
then sed "s/& $site.booking.local/& $site.booking.local m.$site.booking.local/" -i $workdir/$site$dom.conf
else
sed "s/ServerAlias.* /& m.$site.booking.local/" -i $workdir/$site$dom.conf
flagmobile="1"
fi
Replace
if [ [ $ansmob = "y" ] || [ $flagbook != "1" ] ];
with
if [ "$ansmob" = "y" ] || [ "$flagbook" != "1" ]
with bash's double brackets, you can use && and ||
if [[ $ansmob = "y" || $flagbook -ne 1 ]]
Within double brackets, it's not strictly necessary to quote the variables: this command is smart about evaluating expressions with empty variables.
The binary && operator is the syntax for the AND operation.
I am trying to combine two conditions that checks for character values or a null value. For some reason they only work separately, when I try to combine them together in an "or" it gives me errors. Am I missing something?
RETENTION= #either a character value or null value
if [[ "$RETENTION" == +([a-zA-Z]) ]] || [ -z "$RETENTION"] ; then
#bad input
#exit 1
using an elif to do it separately will not work either. Only one condition works.
You have a typo in your condition:
if [[ "$RETENTION" == +([a-zA-Z]) ]] || [ -z "$RETENTION" ] ; then
Should be:
if [[ "$RETENTION" == +([a-zA-Z]) ]] || [ -z "$RETENTION" ] ; then
You had the double square bracket closed before your OR conditio
UPDATE
Actual resolution is to swap the order of the conditions:
if [ -z "$RETENTION" ] || [[ "$RETENTION" == +([a-zA-Z]) ]] ; then