#bash #options
#удар #Опции
Вопрос:
Я использую следующий код. Мое намерение состоит в том, чтобы напечатать некоторую информацию об использовании в зависимости от значения, связанного с -u
.
Например, если у меня есть вызов heading -u1
и heading -u2
, я получаю правильную информацию, отображаемую с использованием условий обращения (1)
и (2)
.
Но я сталкиваюсь с проблемой при использовании just heading -u
. В такой ситуации я хочу напечатать использование заголовка, которое появляется, когда $# == 0
. Я заметил , что при вызове heading -u
функция heading_usage
$1
пустая, но $#
есть 1
.
heading_usage () { printf '%sn' "heading_usage .$*. $#" if (( $# == 0 )); then printf '%sn' " heading [OPTIONS] HEADING" fi case $1 in (1) printf '%sn' " Some Information" ;; (2) printf '%sn' "Additional Information" ;; esac } heading () { while (( $# gt; 0 )); do case $1 in ("-u"|"--usage") usg="$2" ; shift ; shift heading_usage "$usg" return 0 ;; ("-u="*|"--usage="*) usg="${1#*=}" ; shift 1 heading_usage "$usg" return 0 ;; ("-u"*) usg="$2" ; shift ; shift printf '%sn' "usg: .$usg." heading_usage "$usg" esac done }
Комментарии:
1. Что касается
the function heading_usage has $1 empty
— нет,$1
в вашем коде никогда не бывает пусто , так как вы всегда вызываете функцию какheading_usage "$usg"
, то в сценарии, о котором вы спрашиваете, это почти наверняка пустая строка""
.2. Что-то, что следует учитывать: инструменты Unix обычно имеют
-h/--help
аргументы, а не-u/--usage
. Обычно у них внутри естьusage()
функция, которая вызывается при-h/--help
передаче в командной строке, а также при внутреннем вызове в случае ошибок.3. Вы действительно должны использовать
getopts
илиgetopt
обрабатывать разбор аргументов за вас. Если вы не можете понять, как заставить их работать с тем, что вы хотите сделать, то то, что вы хотите сделать, не соответствует обычному внешнему виду команд Unix, и поэтому вам следует переосмыслить свой интерфейс.
Ответ №1:
("-u"*) usg="$2" ; shift ; shift
Это не $2
так — это один аргумент -u
, и он $1
есть , и это один аргумент , так что не надо shift;shift
, а только один shift
.
"-u"*) usg="${1#-u}" ; shift
Не изобретайте велосипед — настоятельно рассмотрите возможность использования getopts
(портативные опции, но только короткие опции) или GNU getopt
(непереносимый вариант, специфичный для Linux, но поддерживает длинные и необязательные опции).
В такой ситуации я хочу напечатать использование заголовка, которое появляется, когда $# == 0
Как Вы указали, похоже "-u"
, что он берет дело в свои руки. Поэтому проверьте, существует ли следующий аргумент:
-u|--usage) if (($# gt; 1)); then usg="$2" heading_usage "$usg" else heading_usage fi return 0 ;;; "-u"*) usg="${1#-u}" shift ... ;;
Комментарии:
1. Спасибо, вы правы, что нуждаетесь в использовании
usg="${1#-u}"
. Проблема, однако, связана с("-u"|"--usage")
. Я думаю, что это$2
возможно, но$2
его не существует.2. Оч, верно, тогда тебе придется с этим справиться. Отдельно. Просто проверьте
if (($# gt; 2)); then usg=$2; else echo "You forgot about argument"; fi
, нигде не проверяйте.3. Я заметил, что если я использую
heading "$usg"
иusg
пусто,$#
вheading_usage
все равно отображается как1
.4. Да, потому что есть один аргумент. Чтобы не передавать никаких аргументов, вы не должны передавать никаких аргументов. Поэтому, если вы хотите исключить пустую переменную, см. Последний фрагмент моего ответа.
5. Тогда имело бы смысл проверить, является ли передаваемое значение допустимым числовым целым числом, а не проверять
$#
.