質問: bashでコマンドライン引数を解析するにはどうすればいいですか? たとえば、この行で呼び出されるスクリプトがあります。./myscript -vfd ./foo/bar/somefile -o /fizz/someotherfile またはこれ:./myscript -v -f -d -o /fizz/someotherfile ./foo/bar/somefile それぞれの場合(またはその2つの組み合わせ)で$v、$f、および$dがすべてtrueに設定され、$outfileが/fizz/someotherfileに等しくなるように、これを構文解析するための一般的な方法は何ですか?
回答: これが私のアプローチです - regexpを使うこと。 何もない 短いパラメータのブロックを処理します-qwerty 短いパラメータを処理します-q -w -e 長いオプションを扱います--qwerty ショートまたはロングオプションに属性を渡すことができます(ショートオプションのブロックを使用している場合、属性は最後のオプションに付加されます)。 スペースや=を使用して属性を指定できますが、属性はハイフン+スペース "delimiter"に遭遇するまで一致します。そのため--q=qwe tyではqwe tyは1つの属性です。 -o a -op attr ibute --option=att ribu te --op-tion attribute --option att-ributeが有効なので、上記すべての組み合わせを処理します。 スクリプト:#!/usr/bin/env sh help_menu() { echo "usage: ${0##*/} [-h][-l filename][-d] options: -h, --help display this help and exit -l, --logfile=filename filename -d, --debug enable debug " } parse_options() { case $opt in h|help) help_menu exit ;; l|logfile) logfile=${attr} ;; d|debug) debug=true ;; *) echo "unknown option: ${opt}\nrun ${0##*/} -h for help.">&2 exit 1 esac } options=$@ until [ "$options" = "" ]; do if [[ $options =~ (^ *(--([a-za-z0-9-]+)|-([a-za-z0-9-]+))(( |=)(([\_\.\?\/\\a-za-z0-9]?[ -]?[\_\.\?a-za-z0-9]+)+))?(.*)|(.+)) ]]; then if [[ ${bash_rematch[3]} ]]; then # for --option[=][attribute] or --option[=][attribute] opt=${bash_rematch[3]} attr=${bash_rematch[7]} options=${bash_rematch[9]} elif [[ ${bash_rematch[4]} ]]; then # for block options -qwert[=][attribute] or single short option -a[=][attribute] pile=${bash_rematch[4]} while (( ${#pile} > 1 )); do opt=${pile:0:1} attr="" pile=${pile/${pile:0:1}/} parse_options done opt=$pile attr=${bash_rematch[7]} options=${bash_rematch[9]} else # leftovers that don't match opt=${bash_rematch[10]} options="" fi parse_options fi done