Причины различного поведения оператора if - bash - PullRequest
1 голос
/ 04 апреля 2011

Рассмотрим следующий фрагмент кода:

#!/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 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 number 57 does not satisfy the condition.
The number 58 does not satisfy the condition.
The number 59 does not satisfy the condition.

С остальными выходными инструкциями, подтверждающими условия для проверки. Они не были вставлены здесь для краткости. У меня вопрос такой:

Числа 30-39 и 50-59, на мой взгляд, удовлетворяют условию оператора if, но вывод является чем-то совершенно нелогичным. Изменение условия оператора if на это:

if [ ${num} -ge 30 ] && [ ${num} -le 39 ] || [ ${num} -ge 50 ] && [ ${num} -le 59 ];  then  

Вывод выглядит так, как и должно быть, и диапазоны 30-39 и 50-59 удовлетворяют условиям. Почему порядок условий так важен в приведенном выше утверждении?

Примечание: я не уверен, что это актуально, но я использую bash версии 4.0.23 (1) -релиз (i386-redhat-linux-gnu)

1 Ответ

4 голосов
/ 04 апреля 2011

Подобные проблемы часто являются проблемой приоритета операторов. То, что вы написали, в основном ((A && B) || C) && D (оценивается слева направо), но вы хотите (A && B) || (C && D).

Если вы ставите скобки вокруг вашего и состояния, оно работает так, как ожидалось:

if ([ ${num} -ge 50 ] && [ ${num} -le 59 ]) || ([ ${num} -ge 30 ] && [ ${num} -le 39 ]); then
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...