2012-02-14 1 views
10

Все, что я вижу, использует getopt или слегка причудливый getopts, который поддерживает только односимвольные параметры (например, -h, но не --help). Я хочу сделать очень долгое время.Как разобрать аргументы длинной формы в оболочке?

+1

Возможный дубликат [Использование getopts в скрипте оболочки bash для получения длинных и коротких параметров командной строки] (http://stackoverflow.com/questions/402377/using-getopts-in-bash-shell-script-to-get -long-and-short-command-line-options) –

+1

@JonathanLeffler Действительно не дубликат как 'getops' не всегда должен быть ответом – Potherca

+1

@Potherca: И действительно,' getopts' - это * не * ответ, так как объяснил как в этом вопросе, так и в ответах на этот вопрос. – ruakh

ответ

14

Я сделал что-то вроде this:

_setArgs(){ 
    while [ "${1:-}" != "" ]; do 
    case "$1" in 
     "-c" | "--configFile") 
     shift 
     configFile=$1 
     ;; 
     "-f" | "--forceUpdate") 
     forceUpdate=true 
     ;; 
     "-r" | "--forceRetry") 
     forceRetry=true 
     ;; 
    esac 
    shift 
    done 
} 

Как вы можете видеть, это поддерживает как одинарной характер и более длинные варианты красиво. Он позволяет связать значения с каждым аргументом, как в случае --configFile. Это также довольно расширяемо, без каких-либо искусственных ограничений в отношении того, какие опции могут быть настроены и т. Д.

Как указано выше, "${1:-}" предотвращает ошибку «несвязанной переменной» при работе в режиме «строгого» режима (set -euo pipefail).

+0

Это будет работать, но не будет подчиняться некоторым соглашениям: складывать однобуквенные аргументы и такие вещи, как '-configFile = filename' (' = '). –

+1

@IanBicking - очень верно. Однако для моего случая я решил разрешить это из-за разочарования, когда getopt/getops повторяется во многих (хотя и ценных) ответах, представленных в отмеченном дубликате по адресу http://stackoverflow.com/questions/402377/using-getopts -в-Баш-оболочки сценария к-получить долгосрочные и краткосрочные-командных строк-вариантов. – ziesemer

+0

А ... этот вопрос не был среди кандидатов на дубликаты, когда я написал свой вопрос. Благодаря! –

6

Предполагая, что вы «хотите делать необычные длинные варианты» независимо от инструмента, просто перейдите с getopt (getopts, похоже, в основном используется, когда важна переносимость). Вот example около максимальной сложности, что вы получите:

params="$(getopt -o e:hv -l exclude:,help,verbose --name "$(basename "$0")" -- "[email protected]")" 

if [ $? -ne 0 ] 
then 
    usage 
fi 

eval set -- "$params" 
unset params 

while true 
do 
    case $1 in 
     -e|--exclude) 
      excludes+=("$2") 
      shift 2 
      ;; 
     -h|--help) 
      usage 
      ;; 
     -v|--verbose) 
      verbose='--verbose' 
      shift 
      ;; 
     --) 
      shift 
      break 
      ;; 
     *) 
      usage 
      ;; 
    esac 
done 

С помощью этого кода вы можете указать более -e/--exclude, чем один раз, и ${excludes[@]} будет содержать все заданные исключает. После обработки (-- всегда присутствует) все остальное хранится в [email protected].

+0

'basename' не принимает путь как параметр, а как аргумент. (Я не мог отредактировать ответ, потому что для этого требуется не менее 6 символов). – jarno

+0

Спасибо @jarno, не знаю, как это провалилось. – l0b0

+1

С другой стороны, я думаю, вам не нужно использовать '$ { 2-} ', но' $ 2' достаточно, так как 'getopt' выйдет с ненулевым кодом, если не было аргумента для' -e', правильно? – jarno

 Смежные вопросы

  • Нет связанных вопросов^_^