getops: Bedingung zur Einschränkung der Eingabemöglichkeiten

getops: Bedingung zur Einschränkung der Eingabemöglichkeiten

Ich habe ein Shell-Skript, das 4 Eingabeoptionen akzeptiert (x:m:b:v). Aber ich möchte meine Eingabeoptionen wie folgt einschränken:

Bedingung 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

Bedingung 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

Bedingung 3

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

Bedingung 4

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

Ich weiß, dass dies mit if- und else-Bedingungen erreicht werden kann, aber ich verstehe die Logik hinter den Bedingungen nicht.

Auch wenn keines der Eingabeargumente übergeben wird (oder) wenn alle Eingabeargumente übergeben werden, sollte die Verwendungsfunktion ausgeführt werden.

Antwort1

Als Beispiel zur Veranschaulichung meines obigen Kommentars hier ein Auszug aus 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;
        }

Beachten Sie, dass oben viele boolesche Variablen wie Hflag, Lflag, lflag, sflag usw. festgelegt werden. Dadurch kann der Code nicht nur boolesche Beziehungen zwischen Flags testen, sondern auch, dass das Vorhandensein eines Flags ein anderes aktiviert oder ein anderes überschreibt. Beachten Sie auch, dass die defaultKlausel der switchAnweisung einen Aufruf erzwingt usage(), wenn der Benutzer ein undefiniertes Optionsflag angibt.

Was Flag-Ausschlüsse betrifft, wie etwa das Nichtzulassen von mflag&& xflag, erscheint ein ähnlicher Fall in cp.c:

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

Hier ist eine mögliche Übersetzung dieses Codes von C bashmit zusätzlichen Anpassungen an Ihr Beispiel:

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'
}

verwandte Informationen