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 default
cláusula de la switch
declaració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 bash
con 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'
}