Передача аргументов в программу – одна из распространенных операций в любом языке, который вы используете.
Так и в этой статье мы рассмотрим, как разбирать аргументы в скриптах bash с помощью встроенной функции getopts.
Введение
Каждая команда, которую мы выполняем в терминале, имеет аргумент, связанный с ней.
Например, можно взять самую простую команду в Linux под названием df, которая отображает использование дискового пространства файловой системы.
Она принимает такие аргументы/флаги, как -h, -i, –version и т.д.
Аналогично этому, когда вы создаете скрипт оболочки, в зависимости от случая использования вам может потребоваться обработать скрипт на основе переданного аргумента.
В bash есть два способа анализа аргументов, переданных скрипту.
Один из них – написать логику для разбора аргументов вручную, используя специальные переменные $@, $1, $2 … $N.
Другой способ заключается в использовании getopts.
Getopts – это POSIX-совместимая встроенная функция bash, которая принимает короткие аргументы, такие как -h, -v, -b и т.д.
Вы не можете передавать длинные аргументы, такие как –help, –version.
Если вы хотите разобрать длинные опции, есть другая утилита getopt, которая является внешней программой, а не встроенной в bash.
Есть три возможных сценария работы с флагами/аргументами.
- Скрипт, который выполняется, даже если не переданы ни аргументы, ни флаги.
- Скрипт, который принимает флаги, но без аргументов.
- Скрипт, принимающий флаги и связанные с ними аргументы для флага.
В последующих разделах вы узнаете, как создать скрипт на bash, удовлетворяющий вышеописанным сценариям.
Основные понятия Getopts
Есть четыре важных термина, о которых вы должны знать, чтобы работать с getopts.
getopts: getopts optstring name [arg …]
- OPTSTRING – Список символов, которые распознаются в качестве аргументов. Пример: -h, -v.
- OPTNAME – Разобранный аргумент из $@ будет сохранен в переменной OPTNAME. Вы можете использовать любое имя в качестве optname.
- OPTARG – Если были переданы дополнительные аргументы, то они сохраняются в переменной OPTARG.
- OPTIND – Индекс, указывающий на следующий обрабатываемый аргумент.
Когда вы передаете аргументы скрипту, они будут храниться в переменной $@.
Getopts получит список аргументов из $@ с помощью OPTIND и разберет его.
Вы должны указать список распознанных аргументов в OPTSTRING.
Цикл While используется для итерации по списку переданных аргументов, а getopts с помощью OPTIND получит аргумент и сохранит его в OPTNAME.
Оператор case используется для проверки совпадения шаблона с OPTNAME и запуска соответствующего оператора.
Я собираюсь выполнять приведенный ниже код на протяжении всей статьи.
Это простой для понимания код.
Сначала я создал функцию с именем “help”, где приведен синтаксис использования моего скрипта.
Я использую три аргумента в OPTSTRING ; “-s, -T, -h”
Переменная с именем ARG – это OPTNAME, используемое в приведенном ниже коде.
Разобранный аргумент будет сохранен в $ARG, и с помощью оператора case он попытается найти, совпадает ли шаблон с аргументом в переменной ARG.
Следующий скрипт принимает такие флаги, как -s, -h, -T, а также вы можете комбинировать флаги, например -shT.
#!/bin/bash function help(){ echo "USAGE: args.sh -s, -T <arg>, -h" } while getopts ":sT:h" ARG; do case "$ARG" in s) echo "Running -s flag" ;; T) echo "Running -T flag" echo "Argument passed is $OPTARG" ;; h) help ;; :) echo "argument missing" ;; \?) echo "Something is wrong" ;; esac done shift "$((OPTIND-1))"
Функциональность приведенного выше кода будет подробно описана в следующем разделе.
Аргумент не передан
По умолчанию getopts ведет себя так: если аргумент не передан, он не выдает сообщения об ошибке и завершает работу с кодом возврата ноль.
В некоторых случаях скрипт не должен выполняться, если не передан ни один аргумент.
В этом случае можно использовать условные операторы, чтобы проверить, равна ли длина переданных аргументов ($@) нулю или нет.
Если аргументы не переданы, скрипт завершится неудачно.
Взгляните на приведенный ниже код.
Я сохраняю переданные аргументы в переменную PASSED_ARGS и проверяю ее длину.
Если длина PASSED_ARGS не равна нулю, то выполняется цикл while с getopts, иначе выполняется функция help и скрипт завершается с кодом возврата 1…
PASSED_AGS=$@ if [[ ${#PASSED_ARGS} -ne 0 ]] then while getopts ":sT:h" ARG; do case "$ARG" in s) echo "Running -s flag" ;; T) echo "Running -T flag" echo "Argument passed is $OPTARG" ;; h) help ;; :) echo "argument missing for $ARG" ;; \?) echo "Something is wrong" ;; esac done else help exit 1 fi shift "$((OPTIND-1))"
Вы также можете использовать следующее однострочное предложение для оценки переданных аргументов.
[[ ${#PASSED_ARGS} -ne 0 ]] && echo "Arguments stored in \$@ = $@" || { echo "No argument passed"; help; exit 1; }
Аргументы с флагами и поддерживаемые ими аргументы
Вы можете либо просто передать скрипту флаги типа -h или -s, либо флаги и связанный с ними аргумент типа -T.
Вам следует добавить двоеточие (:) после идентификатора флага (-T), чтобы заставить флаг принять аргумент.
В приведенном ниже коде видно, что я добавил двоеточие (:) после идентификатора T.
Это означает, что когда я передаю флаг -T скрипту, я должен передать дополнительный аргумент вместе с ним.
while getopts ":sT:h" ARG; do
Когда аргумент передается флагу, он будет сохранен в переменной $OPTARG.
Вам необходимо написать логику, чтобы перехватить переменную и обработать ее соответствующим образом.
Скопируйте и запустите тот же код из предыдущего раздела.
T) echo "Running -T flag" echo "Argument passed is $OPTARG" ;;
Обработка ошибок
Могут возникнуть ситуации, когда аргументы переданы неправильно, и скрипт должен выдать какую-либо ошибку.
По умолчанию getopts выдает сообщение об ошибке, если переданный флаг не находится в OPTSTRING или если вы не передали дополнительные аргументы к флагу.
Добавление двоеточия в начало OPTSTRING подавит сообщения об ошибках по умолчанию.
Давайте уберем двоеточие и запустим сценарий снова.
Я передаю -x в качестве первого аргумента, которого нет в OPTSTRING.
Во-вторых, -T требует дополнительного аргумента, который я не указал.
В обоих случаях выдает ошибку.
Теперь вы можете подавлять сообщения об ошибках по умолчанию и выводить свои собственные сообщения об ошибках.
Посмотрите на приведенные ниже шаблоны из оператора case.
- (:) -> Если не передан дополнительный аргумент, OPTARG будет установлен на двоеточие, и вы можете написать логику для вывода сообщений об ошибках.
- \? -> Если передан аргумент, не входящий в OPTSTRING, OPTNAME будет установлен в “?”.
:) echo "argument missing" ;; \?) echo "Something is wrong" ;;
Использование Shift и OPTIND
Если вы возьмете любой существующий скрипт, написанный с использованием getopts, то увидите это утверждение после цикла while.ogic для вывода сообщений об ошибках.
shift "$((OPTIND-1))"
Когда скрипт запускается, OPTIND устанавливается в 1. OPTIND указывает на позицию следующего аргумента, обрабатываемого getopts.
Приведенное выше утверждение удалит все опции, обработанные getopts, и $1 не будет установлен в первый неопциональный аргумент, переданный скрипту.
Заключение
В этой статье мы рассмотрели, как разбирать аргументы в сценариях bash с помощью функции getopts.
Getopts поддерживает только короткую форму аргументов, и вы не можете передавать длинные аргументы.
Поначалу работа с getopts может показаться сложной, но если вы поймете основную конструкцию, то все станет проще.
см. также:
- 🐧 Полезные сочетания клавиш в оболочке bash для навигации по командной строке.
- 📜 Скрипты Bash для сканирования и мониторинга сети
- 🐧 Как вывести список имен файлов и их содержимое на Linux bash
- 🌐 Проверка доступности доменного имени с помощью bash и whois
- 🐧 Как использовать зашифрованный пароль в скриптах Bash
- 🐧 Операторы Bash if: if, elif, else, then, fi
- 🐧 Функция Bash для извлечения файловых архивов различных типов