🐧 Bash скриптинг – парсинг аргументов в скриптах Bash с помощью getopts |

🐧 Bash скриптинг – парсинг аргументов в скриптах Bash с помощью getopts

Мануал

Передача аргументов в программу – одна из распространенных операций в любом языке, который вы используете.

Так и в этой статье мы рассмотрим, как разбирать аргументы в скриптах 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 может показаться сложной, но если вы поймете основную конструкцию, то все станет проще.

см. также:

 

Пожалуйста, не спамьте и никого не оскорбляйте. Это поле для комментариев, а не спамбокс. Рекламные ссылки не индексируются!
Добавить комментарий