Выбрать главу

С командой getopts очень тесно взаимосвязаны скрытые переменные. $OPTIND -- указатель на аргумент (OPTion INDex) и $OPTARG (OPTion ARGument) -- дополнительный аргумент опции. Символ двоеточия, следующий за именем опции, указывает на то, что она имеет дополнительный аргумент.

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

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

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

3. Пример getopts, заменившей устаревшую, и не такую мощную, внешнюю команду getopt.

while getopts ":abcde:fg" Option

# Начальное объявление цикла анализа опций.

# a, b, c, d, e, f, g -- это возможные опции (ключи).

# Символ : после опции 'e' указывает на то, что с данной опцией может идти

# дополнительный аргумент.

do

case $Option in

a ) # Действия, предусмотренные опцией 'a'.

b ) # Действия, предусмотренные опцией 'b'.

...

e) # Действия, предусмотренные опцией 'e', а так же необходимо обработать $OPTARG,

# в которой находится дополнительный аргумент этой опции.

...

g ) # Действия, предусмотренные опцией 'g'.

esac

done

shift $(($OPTIND - 1))

# Перейти к следующей опции.

# Все не так сложно, как может показаться ;-)

Пример 11-17. Прием опций/аргументов, передаваемых сценарию, с помощью getopts

#!/bin/bash

# ex33.sh

# Обработка опций командной строки с помощью 'getopts'.

# Попробуйте вызвать этот сценарий как:

# 'scriptname -mn'

# 'scriptname -oq qOption' (qOption может быть любой произвольной строкой.)

# 'scriptname -qXXX -r'

#

# 'scriptname -qr' - Неожиданный результат: "r" будет воспринят как дополнительный аргумент опции "q"

# 'scriptname -q -r' - То же самое, что и выше

# Если опция ожидает дополнительный аргумент ("flag:"), то следующий параметр

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

NO_ARGS=0

E_OPTERROR=65

if [ $# -eq "$NO_ARGS" ] # Сценарий вызван без аргументов?

then

echo "Порядок использования: `basename $0` options (-mnopqrs)"

exit $E_OPTERROR # Если аргументы отсутствуют -- выход с сообщением

# о порядке использования скрипта

fi

# Порядок использования: scriptname -options

# Обратите внимание: дефис (-) обязателен

while getopts ":mnopq:rs" Option

do

echo $OPTIND

case $Option in

m ) echo "Сценарий #1: ключ -m-";;

n | o ) echo "Сценарий #2: ключ -$Option-";;

p ) echo "Сценарий #3: ключ -p-";;

q ) echo "Сценарий #4: ключ -q-, с аргументом \"$OPTARG\"";;

# Обратите внимание: с ключом 'q' должен передаваться дополнительный аргумент,

# в противном случае отработает выбор "по-умолчанию".

r | s ) echo "Сценарий #5: ключ -$Option-"'';;

* ) echo "Выбран недопустимый ключ.";; # ПО-УМОЛЧАНИЮ

esac

done

shift $(($OPTIND - 1))

# Переход к очередному параметру командной строки.

exit 0

Управление сценарием

source, . (точка)

Когда эта команда вызывается из командной строки, то это приводит к запуску указанного сценария. Внутри сценария, команда source file-name загружает файл file-name. Таким образом она очень напоминает директиву препроцессора языка C/C++ -- "#include". Может найти применение в ситуациях, когда несколько сценариев пользуются одним файлом с данными или библиотекой функций.