Bash optarg не может найти пропущенные аргументы - PullRequest
0 голосов
/ 17 апреля 2020

Я неопытен с bash сценариями оболочки и столкнулся с проблемой с bash optarg

Вот небольшой сценарий для воспроизведения проблемы:

#!/bin/sh

while getopts ":a:b:"  opt; do
  case ${opt} in
    a ) echo "a=$OPTARG"
     ;;
    b ) echo "b=$OPTARG"
      ;;
    \? ) echo "Invalid option: $OPTARG" 1>&2 
      ;;
    : ) echo "Invalid option: $OPTARG requires an argument" 1>&2
  esac
done

Когда я пытаюсь это сделать:

./args.sh -a av -b bv

я получаю ожидаемый результат:

a=av
b=bv

Но когда я опускаю аргумент для -a:

/args.sh -a -b bv

, я получаю этот неудачный результат:

a=-b

Когда я ожидал, что ошибка покажет, что значение -a отсутствует.

Кажется, он принял аргумент -b в качестве значения для - а. Я сделал что-то не так и как мне добиться ожидаемого поведения?

Ответы [ 2 ]

3 голосов
/ 17 апреля 2020

Единственный положительный совет - как вы относитесь к Но когда я опускаю аргумент для '-a', вы не можете просто перейти к следующей последующей опции. По соглашению getopts a: означает, что вы ожидаете предоставить значение arg для определенного флага.

Так что даже для пропущенного случая вам нужно определить пустую строку, которая означает, что значение для arg не определено, т. Е.

-a '' -b bv

Или если вы не ожидаете -a чтобы получить любые значения arg, лучше измените строку параметров, чтобы она не получалась как :ab:.

Любые другие способы обойти, проверив, не содержит ли OPTARG для -a значение - или другие хаки не рекомендуется, поскольку это не соответствует рабочему процессу getopts().

1 голос
/ 17 апреля 2020

getopts не поддерживает такое обнаружение. Так что с getopts.

сделать это невозможно. Возможно, вместо аргументов вы можете написать al oop. что-то вроде:

#!/bin/sh

check_option()
{
    case $1 in
        -*)
            return 1
        ;;
    esac

    return 0
}

for opt in $@; do
  case ${opt} in
    -a) shift
        if check_option $1; then
            echo "arg for -a: $1"
            shift
        else
            echo "Invalid option -a"
        fi
     ;;
    -b) shift
        if check_option $1; then
            echo "arg for -b: $1"
            shift
        else
            echo "Invalid option -b"
        fi
     ;;
  esac
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...