Reasons for different behaviour of if statement - bash
Consider the following code snippet:
#!/bin/bash
#This program tests the if statement in bash.
for num in {0..99}
do
if [ ${num} -ge 50 ] && [ ${num} -le 59 ] || [ ${num} -ge 30 ] && [ ${num} -le 39 ]; then
echo "The number ${num} satisfies the condition."
else
echo "The number ${num} does not satisfy the condition."
fi
done
The output for the above statement is:
The number 30 satisfies the condition.
The number 31 satisfies the condition.
The number 32 satisfies the condition.
The number 33 satisfies the condition.
The number 34 satisfies the condition.
The number 35 satisfies the condition.
The number 36 satisfies the condition.
The number 37 satisfies the condition.
The number 38 satisfies the condition.
The number 39 satisfies the condition.
The number 50 does not satisfy the condition.
The number 51 does not satisfy the condition.
The number 52 does not satisfy the condition.
The number 53 does not satisfy the condition.
The number 54 does not satisfy the condition.
The number 55 does not satisfy the condition.
The number 56 does not satisfy the condition.
The nu开发者_JAVA百科mber 57 does not satisfy the condition.
The number 58 does not satisfy the condition.
The number 59 does not satisfy the condition.
With the rest of the output statements confirming to the conditions being checked for. They have not been pasted here for brevity. My question is this:
The numbers 30-39 and 50-59 both, in my opinion, satisfy the if statement condition, yet the output is something totally counter-intuitive. Changing the if statement condition to this:
if [ ${num} -ge 30 ] && [ ${num} -le 39 ] || [ ${num} -ge 50 ] && [ ${num} -le 59 ]; then
The output appears as it should, with both 30-39 and 50-59 ranges satisfying the conditions. Why is the order of conditions so important in the above statement?
Note: I am not sure if this is relevant, but I am using bash version 4.0.23(1)-release (i386-redhat-linux-gnu)
Problems like this are often a problem of precedence with the operators. What you wrote is basicly ((A && B )|| C) && D (its evaluated left to right), but you want (A && B) || (C && D).
If you make brackets around your and condition it works like expected:
if ([ ${num} -ge 50 ] && [ ${num} -le 59 ]) || ([ ${num} -ge 30 ] && [ ${num} -le 39 ]); then
精彩评论