Как использовать операторы case .. esac в Bash
В этом руководстве мы рассмотрим условные операторы Bash на основе регистра. Мы рассмотрим практические примеры и обсудим, когда оператор Bash case .. esac лучше всего использовать вместо более традиционного оператора if .. then .. fi
.
Bash case .. Операторы esac в Bash
По умолчанию доступные в оболочке Bash условные операторы case, сформулированные с использованием идиом case
и esac
(идиома — это слово или группа слов, или ключевое слово, с установленные шаблоны использования; форма выражения компьютерного языка), можно построить сложный условный оператор поиска и выполнения для каждого случая (отсюда и термин case
).
Поисковая часть оператора, основанного на регистре, иногда называется выбрать, что приводит к термину выбор/оператор случая (или наоборот), используемому в некоторых других языках кодирования, таких как VBA. , чтобы обратиться к тому же типу парадигмы программирования. В еще одном наборе языков (таких как C#, C++, Java и JavaScript) это называется оператором switch или switch/case. Все они имеют схожие значения и операции.
Давайте создадим наш первый оператор case .. esac
, используя простой скрипт.
Простой случай.. скрипт esac
Мы определяем наш тестовый скрипт test.sh
следующим образом:
#!/bin/bash case "${1}" in 1) echo "Option was 1!";; 2) echo "Option was 2!";; *) echo "Option was something else: '${1}'";; esac
Затем мы делаем наш скрипт исполняемым, выполнив chmod +x test.sh
, а затем выполняем сам скрипт, каждый раз передавая в качестве входных данных разные параметры.
В нашем открывающем предложении case мы указываем, что хотим использовать первую опцию ввода ($1
) в качестве оцениваемой переменной. Наш оператор case .. esac
проверит каждую опцию (как указано в тексте, предшествующем )
закрывающей идиоме предложения), а затем обработает блок кода (после )
идиома) для правильного результата.
Обратите внимание, что в конце каждой строки есть два знака конца оператора ;
. Причина этого проста; нормальный синтаксис Bash требует, чтобы у вас была хотя бы одна завершающая идиома ;
(если вы уже не находитесь в конце строки), но внутри оператора case .. esac
мы нужен дополнительный ;
, чтобы указать, что мы завершаем блок кода для конкретного блока выполнения кода case.
Мы можем видеть, как мы определили код для обоих случаев, когда 1
и 2
передаются сценарию соответственно. Однако что происходит, когда мы передаем что-то еще? В этом случае мы хотим перейти к нашему предложению other, обозначенному универсальной идиомой *
.
Мы видим, как мы передаем в скрипт 1
или 2
, совершается соответствующее правильное действие; Вариант был 1/2!
. Мы также видим, что если мы делаем что-то еще, блок кода *
выполняется правильно, и наша первая переменная, переданная в скрипт, также хорошо отображается. Что произойдет, если мы не передадим скрипту никаких опций? Код case .. esac
все равно будет оцениваться, и, поскольку ничего не совпадает, кроме нашего общего предложения *
, оно выполняется:
Итак, что произойдет, если мы предположим, что может показаться логичным, что мы можем опустить один оператор ;
в конце строки каждого case .. esac
просто потому, что одновременно достигается EOL (конец строки)?
Обратите внимание, что в этом скрипте использовался только один завершающий ;
. Bash этого не позволяет, и выдается ошибка; требуется окончательный завершающий синтаксис ;;
, и что-то нужно иметь в виду при написании операторов case .. esac
Почему случай .. esac А не если?
Мы также могли бы написать предыдущий код, используя оператор if
:
#!/bin/bash if [ "${1}" == "1" ]; then echo "Option was 1!" elif [ "${1}" == "2" ]; then echo "Option was 2!" else echo "Option was something else: '${1}'"; fi
Это выглядит сравнимым по качеству и краткости кода с нашим кодом case .. esac
, и в данных ситуациях и конкретных случаях использования, подобных этим, часто используется if .. then .. elif . .else ..решение на основе fi
вполне подойдет.
Тем не менее, если и когда сложность выбора становится более сложной или большой, или если необходимо выполнить многоуровневый выбор варианта (обратите внимание, что case .. esac
может быть вложенным), он может вместо этого используйте операторы case .. esac
.
Еще одна приятная особенность операторов case .. esac
заключается в том, что можно перечислить два возможных варианта для одного блока выполнения кода, как мы увидим в нашем следующем примере, однако это также можно сделать с помощью стандартного Bash < операторыif, используя, например, параметры -a
(and) и -o
(or) из нашего тестового предложения и указывая вторичное тестовое предложение . Например, if [ \$ {1}\ -eq 1 -o \$ {1}\ -eq 3 ]; затем ...
Обратите внимание, что здесь мы также использовали числовые сравнения вместо текстовых сравнений, как в нашем примере выше.
Для получения дополнительной информации об условных выражениях if .. then .. else .. elif .. fi
вы также можете прочитать нашу статью Условное тестирование в Bash: if, then, else, elif.
Расширение нашего дела
Давайте расширим наш предыдущий сценарий и немного усложним наши условия:
#!/bin/bash case "${1}" in 1|3) echo "Option was 1!" echo "Or, option was 3!";; 2|'a') case "${1}" in 2) echo "Option was 2!";; 'a') echo "Option was 'a'!";; esac;; *) echo "Option was something else: '${1}'";; esac
В этом случае мы перечислили два возможных варианта для каждого блока кода и разделили их разделителем |
. Обратите внимание, что все работает хорошо, а входные данные 1
и 3
анализируются правильно. Во втором блоке кода мы создали вложенный блок и использовали каждый возможный ввод во второй блок кода (а именно 2
и a
) в качестве новых опций во вложенном/вторичном блоке. esac.
Это снова работает безупречно. Поток кода таков, что в первом операторе case
ветвь 2|a
принимается как 2
или a
передается, а затем второй case
гарантирует, что либо 2
, либо a
выбраны индивидуально. Интересно также использование ;;
каждый раз, когда мы хотим завершить блок кода для определенной опции, и это также относится к завершению вложенного case .. esac
, снова с помощью ;;
, то есть esac;;
.
Подведение итогов
В этом руководстве мы рассмотрели практические примеры операторов case .. esac
на основе Bash. Мы также видели, где операторы case являются лучшим выбором, чем более традиционные операторы на основе if .. then .. fi
.
Если вас интересует Bash, вас могут заинтересовать Primer: Bash Loops: for, while и until, Bash Process Termination Hacks и How to Correctly Parse File Names in Bash.
Наслаждайтесь!