Функция использования с номерами выходных уровней

#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. Тогда имело бы смысл проверить, является ли передаваемое значение допустимым числовым целым числом, а не проверять $# .