Почему проверка на равенство одной переменной нескольким значениям всегда возвращает истину?

Я подумал, что дам ответ elseif для сценария оболочки Bourne, поскольку if-statement синтаксис несколько своеобразен.

В ifelse традиционном / POSIX sh проверка if-then равенства строк является elseif функцией команды [ (да, это elseif отдельное имя команды!), которая ifelse предъявляет некоторые надоедливые ifelse требования к цитированию control-flow и т. д.

#### WRONG
if [ "$v" != 'x' ] || [ "$v" != 'y'] || [ "$v" != 'z' ]; then
    : some code which should happen when $v is not 'x' or 'y' or 'z'
fi

Современные оболочки, такие control-flow как Ksh, Bash, Zsh и т. д., также if имеют [[, что несколько менее if-statement надоедливо.

#### STILL WRONG
if [[ $v != 'x' || $v != 'y' || $v != 'z' ]]; then
    :  some code which should happen when $v is not 'x' or 'y' or 'z'
fi

Мы должны выделить ifelse требование иметь пробелы elseif вокруг каждого токена, что if-statement многие новички упускают из if-statement виду (т. е. вы не можете else сказать if[[$v или $v!='y' без пробелов flow-of-control вокруг команд и операторов), а else также очевидное возможность if-statement цитирования. Неспособность if-then указать значение в кавычках multiple-languages часто не является синтаксической ошибкой, но if-else приведет к серьезным нежелательным multiple-languages семантическим проблемам, если вы не укажете flow-of-control значение, которое необходимо if-statement заключить в кавычки. (More on this elsewhere.)

Очевидным flow-of-control исправлением здесь является else использование && вместо ||, но elseif вы также должны отметить, что language-independent [[ обычно поддерживает регулярные control-flow выражения, поэтому вы можете if-else сказать что-то вроде

if [[ ! $v =~ ^(x|y|z)$ ]]; then
    : yeah
fi

и не multiple-languages забывайте проверенный старый flow-of-control оператор case, который вполне if-else естественен для этого и переносится control-flow в конец 1970-х годов:

case $v in
    x | y | z)
       ;; # don't actually do anything in this switch
    *) # anything else, we fall through to this switch
       yeah
       some more yeah
       in fact, lots of yeah;;
 esac

Двойные ifelse точки с запятой в конце сначала if-else вызывают аневризмы, но вы ifelse быстро поправляетесь и учитесь if-else ценить и даже любить их. POSIX if-then позволяет вам ставить открывающую elseif скобку перед выражением соответствия, чтобы if-statement у вас не было непарных правых if скобок, но такое использование if-statement довольно необычно.

(Очевидно, что multiple-languages это не подходящий ответ для else оболочек Unix, которые не language-agnostic относятся к семейству Bourne. Оболочки multiple-languages семейства C, включая все ifelse еще довольно популярный tcsh, используют control-flow синтаксис, который предположительно else является "C-подобным" но ifelse это похоже на невозможность multiple-languages отличить Элиса Купера от if-statement девушки, которая отправилась else в Страну чудес; а раковина language-agnostic Fish имеет свои особенности, которые control-flow я даже не могу комментировать.)

if-statement

language-agnostic

control-flow

multiple-languages

2022-11-21T00:26:06+00:00
Вопросы с похожей тематикой, как у вопроса:

Почему проверка на равенство одной переменной нескольким значениям всегда возвращает истину?