getops: условие ограничения входных параметров

getops: условие ограничения входных параметров

У меня есть скрипт оболочки, который принимает 4 варианта ввода (x:m:b:v). Но я хочу ограничить свой вариант ввода, например.

Условие 1

1. Accept option x or x and b
   eg: sh script -x <arg> (or)             ;will execute function a defined in script
       sh script -x <arg> -b               ;will execute the functions a and b

Условие 2

2. Accept option m or m and b
   eg: sh script -m <arg> (or)     ;execute function c
       sh script -m <arg1> -b   ;should execute function for c and b

Условие 3

3. Option both x and m should not be passed together.
   This will print usage(how to use the input options) function.

Условие 4

4. Option v. This should not be passed with any other option.
   eg: sh script -v <arg>  ; executs the function for v

Я знаю, что этого можно добиться с помощью условий if и else, но я не могу понять логику условий.

Кроме того, если ни один из входных аргументов не передан (или) если переданы все входные аргументы, следует выполнить функцию использования.

решение1

В качестве примера, иллюстрирующего мой комментарий выше, приведу отрывок из FreeBSD /usr/src/bin/cp/cp.c:

while ((ch = getopt(argc, argv, "HLPRafilnprsvx")) != -1)
        switch (ch) {
        case 'H':
                Hflag = 1;
                Lflag = 0;
                break;
        case 'L':
                Lflag = 1;
                Hflag = 0;
                break;
        ...
        case 'l':
                lflag = 1;
                break;
        ...
        case 's':
                sflag = 1;
                break;
        case 'v':
                vflag = 1;
                break;
        case 'x':
                fts_options |= FTS_XDEV;
                break;
        default:
                usage();
                break;
        }

Обратите внимание, что вышеприведенный пример устанавливает множество булевых переменных, таких как Hflag, Lflag, lflag, sflag и т. д. Это не только позволяет коду проверять булевы отношения между флагами, но и позволяет присутствию одного флага активировать другой или переопределять другой. Также обратите внимание, что предложение defaultоператора switchпринудительно вызывает usage()вызов, когда пользователь указывает неопределенный флаг опции.

Что касается исключений флагов, таких как запрет mflag&& xflag, аналогичный случай появляется в cp.c:

if (lflag && sflag)
        errx(1, "the -l and -s options may not be specified together");

Вот возможный перевод этого кода с языка C на язык bashс дополнительной адаптацией к вашему примеру:

flagb=
flagm=
flagv=
flagx=

while getopts "bm:vx:" ch
do

        case "$ch" in
        [bv])
                eval flag$ch=1
                printf 'flag%s set\n' "$ch"
                ;;
        [mx])
                eval flag$ch=1
                eval arg$ch=\"$OPTARG\"
                printf 'flag%s set\n' "$ch"
                printf 'arg%s is "%s"\n' "$ch" "$OPTARG"
                ;;
        -)
                break
                ;;
        esac

done

[[ $OPTIND > 1 ]] && shift $(($OPTIND-1))

if [[ "$flagv" ]]
then
        if [[ -n "$flagb$flagm$flagx" ]]
        then
                printf 'error: -v cannot be used with any other flags\n' >&2
                exit 2
        fi
fi

if [[ "$flagm$flagx" = "11" ]]
then
        printf 'error: -m and -x cannot be used together\n' >&2
        exit 2
fi

if [[ "$flagb" ]] && ! [[ "$flagm$flagx" ]]
then
        printf 'error: -b requires either -m or -x\n' >&2
        exit 2
fi

[[ "$flagb" ]] && printf 'b flag is set\n'
[[ "$flagm" ]] && printf 'm flag is set, arg is "%s"\n' "$argm"
[[ "$flagv" ]] && printf 'v flag is set\n'
[[ "$flagx" ]] && printf 'x flag is set, arg is "%s"\n' "$argx"

[[ "$@" ]] && {
        printf 'remaining arguments:'
        printf ' "%s"' "$@"
        printf '\n'
}

Связанный контент