Поиск по сайту:

Как использовать операторы 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.

Наслаждайтесь!