Объединить логические условия оболочки с выборочным приоритетом

#shell

#оболочка

Вопрос:

У меня есть два условия в начале скрипта для проверки аргументов. Предполагается, что должно быть передано ровно два аргумента, и первым аргументом должно быть "FOO" или "BAR" . То, что у меня есть ниже, работает, но я хочу знать, как сделать это одним оператором if:

 #!/bin/bash

if [ "$#" -ne 2 ]; then
        echo "Usage: $0 <FOO or BAR> <Removed for SO>"
        exit
fi
if [ "$1" != "FOO " -a "$1" != "BAR" ]; then
        echo "Usage: $0 <FOO or BAR> <Removed for SO>"
        exit
fi
  

Просто чтобы уточнить, я спрашиваю, как вообще сочетать «логическое и» с «логическим или» в сценарии оболочки. В псевдокоде это то, что я хотел бы:

 if ( numArgs != 2 || (someArg != "FOO" amp;amp; someArg  != "BAR") )
  

Ответ №1:

Вы можете использовать || между 2 условиями:

 if [ "$#" -ne 2 ] || [ "$1" != "FOO" -a "$1" != "BAR" ]; then
        echo "Usage: $0 <FOO or BAR> <Removed for SO>"
        exit
fi
  

Комментарии:

1. Имеет ли -a условие справа более высокий приоритет, чем || ?

2. Приоритет не нужен, поскольку все, что после || , находится в [ ... ] which means [ ... ] , будет оцениваться отдельно.

Ответ №2:

Вы могли бы использовать сопоставление регулярных выражений:

 if [[ $# != 2 amp;amp; ! $1 =~ ^(FOO|BAR)$ ]]
then
   ...
fi
  

Это имеет то преимущество, что его легче адаптировать, если для первого параметра должно быть разрешено больше значений.

Однако я бы не стал объединять оба условия в одно, а оставил их отдельно и предоставил разные сообщения об ошибках для обоих.