If statment in bash with multiple groups? - bash

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

Related

How to include multiple (and or) conditions in a single if statement in a shell script

How to include , multiple and or conditions in a single if statement.
So far i tried :
if [[ "$op_type" == "roll" ]] || [[("$Action" == "up" && "$Status" == "Failed")]] || [[("$Action" == "up" && "$Status" == "InProgress")]] ; then

Bash Multiple conditions in while loop

I'm trying to get a simple while loop working in bash that uses four conditions, but after trying many different syntax from various forums, I can't find solution.
When i write 'Prod' or 'Dev' or 'Admin', i stay in the loop.
while [ -z $vmProfil ] || [ $vmProfil != 'Prod' ] || [ $vmProfil != "Dev" ] || [ $vmProfil != "Admin" ]
do
read -p 'Choose vm profil between Prod, Dev or Admin :' vmProfil
done
You are using || where you should be using &&; no matter what value vmProfil has, at least on of the != conditions must be true.
while [ -z "$vmProfil" ] || { [ "$vmProfil" != 'Prod' ] && [ "$vmProfil" != "Dev" ] && [ "$vmProfil" != "Admin" ]; }
You can also check negate the result of checking if any condition is true.
while [ -z "$vmProfil" ] || ! { [ "$vmProfil" = 'Prod' ] || [ "$vmProfil" = "Dev" ] || [ "$vmProfil" = "Admin" ]; }
I would write this as an infinite loop with an explicit break, though.
while :; do
read -p '...' vmProfil
case $vmProfil in
Prod|Dev|Admin) break ;;
esac
done

bash if clause with and or combined

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.

AND, OR conditions in if statement

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

Shellscript missing ]

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

Resources