PDA

Просмотр полной версии : Программируем в ракушку SHELL. Часть 2 : getopts



mancurt
19.04.2005, 18:03
Экспериментирую с getopts.
:~$ man bash
getopts is used by shell procedures to parse positional parameters...

Тестовый скрипт got (getoptstest):

ALPHA=default
BETTA=default
GAMMA=default
SOMETEXT=default

OPTERR=0

usage()
{
echo "Usage: `basename $0` [-a] [-b betta-data] [-c gamma-data] sometext"
exit 1
}

if [ $# = 0 ]; then
usage
fi

while getopts ab:c: OPTION
do
case $OPTION in
a) ALPHA="a parametr on"
;;
b) BETTA=$OPTARG
;;
c) GAMMA=$OPTARG
;;
?) usage
;;
esac
done

shift `expr $OPTIND - 1`

if [ $# != 1 ]
then
usage
else
SOMETEXT="[email protected]"
fi

echo "alpha = " $ALPHA
echo "betta = " $BETTA
echo "gamma = " $GAMMA
echo "sometext = " $SOMETEXT

ТЗ: скрипт принимает параметры:
-a : просто переключатель, необязательный
-b, -c : опции с указанием значений, необязательные
sometext : просто текст (одно слово), обязательный.
:~$ got -b betta -a test
alpha = a parametr on
betta = betta
gamma = default
sometext = test

:~$ got -b betta test -a
Usage: got [-a] [-b betta-data] [-c gamma-data] sometext

Т.е. если указать sometext до одного из ключей - ошибка. Как можно обойти это "правило" - ключи, обрабатываемые getopts, можно ставить в разном порядке, а sometext - только в конце

banzai
20.04.2005, 11:17
mancurt, я бы сделал внешний цикл, внутри которого уже идет цикл с getopts.
Если после цикла с getopts остается не менее одного параметра, значит первый из них это SOMETEXT,
а оставшиеся (если есть) еще раз на getopts.

mancurt
20.04.2005, 14:33
mancurt, я бы сделал внешний цикл, внутри которого уже идет цикл с getopts.
Если после цикла с getopts остается не менее одного параметра, значит первый из них это SOMETEXT, а оставшиеся (если есть) еще раз на getopts.

Не понял, сорри.
Что циклить во внешнем цикле? параметры?

mancurt
20.04.2005, 14:42
Кроме getopts циклом тогда уж лучше использовать shift. Но именно этого я и хотел бы избежать. С shift работы больше.

Есть еще getopt. В man getopt указано
Example scripts are provided with the getopt(1) distribution, and are optionally installed in /usr/local/lib/getopt or /usr/lib/getopt .
Чего у меня нет 8(

Tigra
20.04.2005, 14:58
лови)

banzai
20.04.2005, 15:10
mancurt, ладно, без цикла.
После shift `expr $OPTIND - 1` вставляешь :
SOMETEXT=$1
OPTIND=2
и еще раз свой цикл с getopts
Должно помочь. ;)

banzai
20.04.2005, 15:14
"Tigra, что это было, море?" :shock:

Tigra
20.04.2005, 15:52
banzai, песочек :)
это был ПРИМЕР :) а вообще фиговый это был пример))
так как ты говоришь, на мой взгляд, не пройдет, потому что в случае когда текст идет перед аргументами - это одна строка. $OPTIND должен быть равен 1 в таком случае.
строку просто парсить надо, можно и без getopts обойтись, если постараться)

banzai
20.04.2005, 16:01
Tigra, а ты попробуй. ;)

$sh got text -a -b betta -c gamma
alpha = a parametr on
betta = betta
gamma = gamma
sometext = text
$

mancurt
20.04.2005, 16:51
mancurt, ладно, без цикла.
После shift `expr $OPTIND - 1` вставляешь :
SOMETEXT=$1
OPTIND=2
и еще раз свой цикл с getopts
Должно помочь. ;)
Это ж не красиво... но все равно, спасибо.

а если еще почекать не состоит ли SOMETEXT из нескольких слов...

banzai
20.04.2005, 16:57
mancurt, тебе и карт... тьфу! ... клаву в руки ;)

mancurt
20.04.2005, 17:16
строку просто парсить надо, можно и без getopts обойтись, если постараться)
тогда можно просто shift и проверять каждый параметр на совпадение с ...

banzai
20.04.2005, 17:28
mancurt, я так понял, что использование getopts было начальным условием.

а если еще почекать не состоит ли SOMETEXT из нескольких слов...
тогда, наверное, имеет смысл писать свой getopts, т.е. "идти по следу Tigra". :-D

mancurt
20.04.2005, 17:36
К этому все движется... Думал "зачем изобретать колесо"...

banzai
21.04.2005, 07:43
BTW, mancurt, а что мешает просто взять
в кавычки sometext (в случае, если он составной)? ;)