getops: condición para restringir las opciones de entrada

getops: condición para restringir las opciones de entrada

Tengo un script de shell que acepta 4 opciones de entrada (x:m:b:v). Pero quiero restringir mi opción de entrada como.

Condición 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

Condición 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

Condición 3

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

Condición 4

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

Sé que esto se puede lograr con las condiciones if y else, pero no puedo entender la lógica de las condiciones.

Además, si no se pasa ninguno de los argumentos de entrada (o) si se pasan todos los argumentos de entrada, debería ejecutar la función de uso.

Respuesta1

Como ejemplo para ilustrar mi comentario anterior, aquí hay un extracto de 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;
        }

Tenga en cuenta que lo anterior establece muchas variables booleanas como Hflag, Lflag, lflag, sflag, etc. Esto no solo permite que el código pruebe las relaciones booleanas entre indicadores, sino que también permite que la presencia de un indicador active otro o anule otro. Observe también que la defaultcláusula de la switchdeclaración fuerza una usage()llamada cuando el usuario especifica un indicador de opción indefinido.

En cuanto a las exclusiones de banderas, como no permitir mflag&& xflag, aparece un caso similar en cp.c:

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

Aquí hay una posible traducción de ese código de C bashcon una adaptación adicional a su ejemplo:

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

información relacionada