Все, что я вижу, использует getopt
или слегка причудливый getopts
, который поддерживает только односимвольные параметры (например, -h
, но не --help
). Я хочу сделать очень долгое время.Как разобрать аргументы длинной формы в оболочке?
ответ
Я сделал что-то вроде 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
).
Это будет работать, но не будет подчиняться некоторым соглашениям: складывать однобуквенные аргументы и такие вещи, как '-configFile = filename' (' = '). –
@IanBicking - очень верно. Однако для моего случая я решил разрешить это из-за разочарования, когда getopt/getops повторяется во многих (хотя и ценных) ответах, представленных в отмеченном дубликате по адресу http://stackoverflow.com/questions/402377/using-getopts -в-Баш-оболочки сценария к-получить долгосрочные и краткосрочные-командных строк-вариантов. – ziesemer
А ... этот вопрос не был среди кандидатов на дубликаты, когда я написал свой вопрос. Благодаря! –
Предполагая, что вы «хотите делать необычные длинные варианты» независимо от инструмента, просто перейдите с 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]
.
'basename' не принимает путь как параметр, а как аргумент. (Я не мог отредактировать ответ, потому что для этого требуется не менее 6 символов). – jarno
Спасибо @jarno, не знаю, как это провалилось. – l0b0
С другой стороны, я думаю, вам не нужно использовать '$ { 2-} ', но' $ 2' достаточно, так как 'getopt' выйдет с ненулевым кодом, если не было аргумента для' -e', правильно? – jarno
Возможный дубликат [Использование getopts в скрипте оболочки bash для получения длинных и коротких параметров командной строки] (http://stackoverflow.com/questions/402377/using-getopts-in-bash-shell-script-to-get -long-and-short-command-line-options) –
@JonathanLeffler Действительно не дубликат как 'getops' не всегда должен быть ответом – Potherca
@Potherca: И действительно,' getopts' - это * не * ответ, так как объяснил как в этом вопросе, так и в ответах на этот вопрос. – ruakh