Разбор аргументов сценария оболочки - PullRequest
18 голосов
/ 15 апреля 2010

Есть множество вопросов по поводу такого рода вещей, но давайте представим, что мы нацелены на общую систему Linux с установленными и getopt, и getopts (не то, что мы будем использовать также, но они кажутся популярными)

Как разобрать как длинные (--example | --example simple-option), так и короткие аргументы (-e | -esimple-example | -e simple-example)

1 Ответ

33 голосов
/ 15 апреля 2010

Вы хотите использовать getopt с длинными и короткими опциями. Пример из рабочего кода:

# Parse arguments
TEMP=$(getopt -n $PROGRAM_NAME -o p:P:cCkhnvVS \
--long domain-password:,pop3-password:\         
,create,cron,kill,help,no-sync-passwords,version,verbose,skip-pop3 \
-- "$@")                                                            

# Die if they fat finger arguments, this program will be run as root
[ $? = 0 ] || die "Error parsing arguments. Try $PROGRAM_NAME --help"       

eval set -- "$TEMP"
while true; do     
        case $1 in 
                -c|--create)
                        MODE="CREATE"; shift; continue
                ;;                                    
                -C|--cron)                            
                        MODE="CRON"; shift; continue  
                ;;                                    
                -k|--kill)                            
                        MODE="KILL"; shift; continue  
                ;;                                    
                -h|--help)                            
                        usage                         
                        exit 0                        
                ;;                                    
                -n|--no-sync-passwords)               
                        SYNC_VHOST=0; shift; continue 
                ;;                                    
                -p|--domain-password)                 
                        DOMAIN_PASS="$2"; shift; shift; continue
                ;;                                              
                -P|--pop3-password)                             
                        POP3_PASS="$2"; shift; shift; continue  
                ;;                                              
                -v|--version)                                   
                        printf "%s, version %s\n" "$PROGRAM_NAME" "$PROGRAM_VERSION"
                        exit 0                                                      
                ;;                                                                  
                -v|--verbose)                                                       
                        VERBOSE=1; shift; continue                                  
                ;;                                                                  
                -S|--skip-pop3)                                                     
                        SKIP_POP=1; shift; continue                                 
                ;;                                                                  
                --)                                                                 
                        # no more arguments to parse                                
                        break                                                       
                ;;                                                                  
                *)                                                                  
                        printf "Unknown option %s\n" "$1"                           
                        exit 1                                                      
                ;;                                                                  
        esac                                                                        
done     

Примечание. die - это функция, которая была определена ранее (не показана).

Опция -n указывает getopt сообщать об ошибках как имя моей программы, а не как getopt. -o определяет список коротких опций (: после того, как опция указывает необходимый аргумент), а --long определяет список длинных опций (соответствует порядку коротких опций).

Остальное - просто простой переключатель, вызывающий shift соответствующим образом для продвижения указателя аргумента. Обратите внимание, что звонить shift; shift; - это просто тяжелая привычка. В современном мире shift 2, вероятно, будет достаточно.

Современный getopt довольно совместим с более новыми платформами, однако вы можете столкнуться с некоторыми проблемами переносимости на старых (около Redhat 9) системах. См. man getopt для получения информации о обратной совместимости. Однако вряд ли вы столкнетесь с необходимостью.

Наконец, после анализа параметров вы можете еще раз позвонить:

eval set -- "$@"

Это переместит указатель аргумента на все остальное, что осталось в командной строке после того, как getopt выполнит параметры разбора. Тогда вы можете просто shift читать дальше. Например, если команда выглядела так:

./foo --option bar file1.txt file2.txt file3.txt

Не забудьте сделать удобную опцию -h / --help, чтобы распечатать новые модные опции, как только вы закончите. :) Если вы сделаете вывод help2man дружественным, у вас есть мгновенная справочная страница для вашего нового инструмента.

Редактировать

В большинстве дистрибутивов вы можете найти больше примеров getopt кода в /usr/share/doc/util-linux/examples, который должен был быть установлен по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...