getopts - встроенная команда Bash, используемая для разбора аргументов, передаваемых скрипту из командной строки. Она позволяет обрабатывать серии опций, объединенных в один аргумент и дополнительные аргументы, передаваемые опцией.

Пример:

# script_name -abc -d /home/user

Вместе с командой getopts используются скрытые переменные: $OPTIND и $OPTARG.

$OPTIND Индекс опции (OPTion INDex).
$OPTARG Дополнительный аргумент опции (OPTion ARGument).

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

while getopts ":abcde:fg" Option

Обычно getopts упаковывается в цикл while, в каждом проходе цикла извлекается очередная опция и ее аргумент (если он имеется), обрабатывается, затем уменьшается на 1 скрытая переменная $OPTIND и выполняется переход к началу новой итерации.

Опциям, передаваемым в сценарий из командной строки, должен предшествовать символ "минус" (-) или "плюс" (+). Этот префикс (- или +) позволяет getopts отличать опции от прочих аргументов. Фактически, getopts не будет обрабатывать аргументы, если им не предшествует символ - или +, выделение опций будет прекращено как только встретится первый аргумент.

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

test-getopts

#!/bin/bash

NO_ARGS=0

usage () {
  echo "Скрипт `basename $0` предназначен для демонстрации возможностей getopts."
  echo ""
  echo "Использование: `basename $0` -abef -c C -d D"
  echo -e "    \033[1mОпции:\033[0m"
  echo "    -a | -b Две опции для одного действия"
  echo "    -c    Опция с аргументом"
  echo "    -d    Еще опция с аргументом"
  echo "    -e    Опция без аргумента"
  echo "    -f    Еще опция без аргумента"
}

if [ $# -eq "$NO_ARGS" ]  # Сценарий вызван без аргументов?
then
  usage                   # Если запущен без аргументов - вывести справку
  exit $E_OPTERROR        # и выйти с кодом ошибки
fi

while getopts "abc:d:ef" Option
do
  case $Option in
    a | b ) echo "Действие 1: опция - $Option. Номер опции: $OPTIND. Аргумент: $OPTARG";;
    c     ) echo "Действие 2: опция - $Option. Номер опции: $OPTIND. Аргумент: $OPTARG";;
    d     ) echo "Действие 3: опция - $Option. Номер опции: $OPTIND. Аргумент: $OPTARG";;
    e     ) echo "Действие 4: опция - $Option. Номер опции: $OPTIND. Аргумент: $OPTARG";;
    f     ) echo "Действие 5: опция - $Option. Номер опции: $OPTIND. Аргумент: $OPTARG";;
    *     ) echo "Выбран недопустимый ключ."
            usage
            exit $E_OPTERROR;;   # ПО-УМОЛЧАНИЮ
  esac
done
shift $(($OPTIND - 1))

exit 0

Попробуйте позапускать его так:

test-getopts -abc с-opt
test-getopts -abefd d-opt

А теперь так:

test-getopts -abcdef
test-getopts -cd d-opt

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

Добавить комментарий