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

Анализ аргументов в сценариях Bash с использованием getopts

Передача аргументов программе — одна из распространенных операций в любом используемом вами языке. Аналогично, в этой статье мы увидим, как анализировать аргументы в сценариях bash с помощью встроенной функции getopts bash в Linux.

Введение

Каждая команда, которую мы запускаем в терминале, имеет связанный с ней аргумент. Например, вы можете использовать самую простую команду Linux под названием df, которая отображает использование дискового пространства файловой системой. Он принимает аргументы/флаги, такие как -h, -i, --version и т. д.

Аналогично этому, когда вы создаете сценарии оболочки, в зависимости от варианта использования вам, возможно, придется обработать сценарий на основе переданного аргумента.

Существует два способа анализа аргументов, передаваемых в сценарий в bash.

Один из них — написание логики для ручного анализа аргументов с использованием специальных переменных $@, $1, $2… $N. Другой способ — использовать getopts.

Getopts — это встроенная функция bash, совместимая с POSIX, которая принимает короткие аргументы, такие как -h, -v, -b и т. д. Вы не можете передать длинные аргументы, такие как --help, --version. Если вы хотите проанализировать длинные параметры, есть еще одна утилита под названием getopt, которая является внешней программой, а не встроенной в bash.

При работе с флагами/аргументами я могу придумать три возможных сценария.

  • Сценарий, который выполняется, даже если не переданы аргументы или флаги.
  • Сценарий, который принимает флаги, но без аргументов.
  • Сценарий, принимающий флаги и связанные с ними аргументы.

В следующих разделах вы узнаете, как создать сценарий bash, удовлетворяющий описанным выше сценариям.

Получать помощь

Вы можете запустить следующую команду справки, чтобы получить доступ к разделу справки getopts.

getopts -help

Основная конструкция Getopts

Есть четыре важных термина, о которых вам следует знать, чтобы работать с getopts.

getopts: getopts optstring name [arg …]
  1. OPTSTRING — список символов, которые распознаются как аргументы. Пример: -h, -v.
  2. OPTNAME – проанализированный аргумент из $@ будет сохранен в переменной OPTNAME. В качестве optname вы можете использовать любое имя.
  3. OPTARG – если переданы дополнительные аргументы, они сохраняются в переменной OPTARG.
  4. OPTIND — индекс, указывающий на следующий аргумент, который будет обработан.

Когда вы передаете аргументы скрипту, они сохраняются в переменной $@. Getopts получит список аргументов из $@ use OPTIND и проанализирует его.

Вам следует указать список распознаваемых аргументов в OPTSTRING. Хотя цикл используется для перебора списка переданных аргументов и использования OPTIND, getopts получит аргумент и сохранит его в 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.

shift "$((OPTIND-1))"

При запуске сценария для OPTIND устанавливается значение 1. OPTIND указывает на позицию следующего аргумента, который будет обработан getopts.

Приведенный выше оператор удалит все параметры, проанализированные getopts, и $1 не будет установлен в качестве первого необязательного аргумента, переданного в сценарий.

Заключение

В этой статье мы увидели, как анализировать аргументы в сценариях bash с помощью функции getopts. Getopts поддерживает только краткую форму аргументов, и вы не можете передавать длинные аргументы.

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

Подобное чтение:

  • Как анализировать файлы CSV в сценариях Bash в Linux

Руководства по написанию сценариев Bash:

  • Как создавать диалоговые окна графического пользовательского интерфейса в сценариях Bash с помощью Zenity в Linux и Unix
  • Сценарии Bash – утверждение случая
  • Сценарии Bash – условные операторы
  • Скрипты Bash: манипулирование строками
  • Сценарии Bash: команда Printf с примерами
  • Скрипты Bash: индексированные массивы с примерами
  • Скрипты Bash: объяснение ассоциативных массивов на примерах
  • Скрипты Bash: цикл For с примерами
  • Скрипты Bash: циклы while и Until с примерами
  • Перенаправление Bash, объясненное примерами
  • Скрипты Bash: переменные, поясняемые примерами
  • Скрипты Bash: функции, поясняемые примерами
  • Команда Bash Echo с примерами для Linux
  • Руководство по Bash Heredoc для начинающих

Статьи по данной тематике