Invocar script de shell con -option y parameters

Necesito invocar un script de shell test.sh de la siguiente manera:

 ./test.sh -run/-rerun username password 

¿Cómo comprobar si han pasado la opción -run o -rerun dentro de mi script de shell?

Un enfoque común es usar la utilidad getopt para dividir las opciones de línea de command pasadas al script para un fácil análisis. getopt admite opciones cortas (caracteres individuales) y largas (caracteres múltiples) con o sin arguments. Cuando se invoca getopt , se pasan dos types de parameters: opciones que modifican la forma en que getopt analizará las opciones y los parameters del script de llamada que se analizarán.

Las opciones más importantes para especificar cómo getopt analizará los arguments restantes son los siguientes:

  • -o, --options shortopts Las opciones cortas que se analizarán. El argumento de shortopts para esta opción es una cadena de caracteres que deben reconocerse como opciones cortas. Un carácter de opción con un argumento requerido debe seguirse con dos puntos : mientras que una opción con un argumento opcional debe ir seguida de dos puntos :: . Por ejemplo, la cadena shortopts ab:c:: corresponde a las siguientes opciones reconocidas -a , -b arg , -c y -c arg . Tenga en count que si no se especifica esta opción, getopt tratará la primera opción que no comienza con - (y no es un argumento de opción) como cadena de shortopts .

  • -l, --longoptions longopts Las opciones largas para ser analizadas. Se puede especificar más de una opción a la vez, separando los nombres de las opciones con comas, o la opción -l se puede dar más de una vez. Los arguments obligatorios y opcionales se indican como con la opción -o con a : o :: siguiendo el nombre de la opción.

  • -a, --alternative Una convención común, especialmente con el software GNU , es que las opciones largas se anteponen con dos guiones, por ejemplo, --run . La opción -a le dice a getopt que permita que las opciones largas comiencen con un solo carácter.

  • -q,--quiet Si getopt encuentra una opción no reconocida o un argumento requerido que falta en los parameters a analizar, imprimirá un post de la forma getopt: unrecognized option '[option name]' o getopt: option '[option name'] requires an argument para stderr , genera la salida normal a stdout y sale con un estado distinto de cero. La opción -q se puede usar para suprimir los posts de error.

  • -n, --name progname Esta opción se puede usar para especificar el nombre del progtwig que getopt utilizará al informar los errores mencionados anteriormente.

El primer parámetro no opcional (que no es un argumento de opción o que se trata como shortopts cadena de shortopts como se describe anteriormente) es tratado por getopt como el inicio de la list de parameters que se analizará. El inicio de estos parameters también se puede indicar con -- , en cuyo caso el primer parámetro después de -- se trata como el inicio de la list de parameters a analizar.

La salida normal de getopt es una list ampliada de las opciones reconocidas de la siguiente manera:

  • Las opciones cortas dadas juntas, por ejemplo, -abc , se expanden a opciones individuales, es decir, -a -b -c .

  • Si -a se especifica como una opción para getopt , las opciones largas que comienzan con un solo guión, por ejemplo -foo , reciben el prefijo con un guión adicional, es decir, --foo .

  • Los arguments obligatorios y opcionales para las opciones se citan, por ejemplo, -b arg convierte en -b 'arg' , --foo arg y --foo=arg convierten en --foo 'arg' .

  • Cualquier argumento restante se cita y se separa de las opciones con -- .

La ventaja de la expansión es que es más fácil analizar las opciones descompuestas ya que quedan pocos casos por considerar. A continuación, se proporciona un ejemplo del análisis de opciones de command-line usando getopt como se especifica en la pregunta:

 #!/bin/bash OPTS=`getopt -a -l run -l rerun -- "$0" "$@"` if [ $? != 0 ] # There was an error parsing the options then exit 1 fi eval set -- "$OPTS" while true; do case "$1" in --run) echo "option --run specified"; shift;; --rerun) echo "option --rerun specified"; shift;; --) shift; break;; esac done echo "Args:" for arg # Process remaining arguments do echo $arg done 

Explicación:

 OPTS=`getopt -a -l run -l rerun -- "$0" "$@"` 

Aquí establecemos la variable OPTS para contener la salida de la invocación getopt . Los arguments pasados ​​a getopt aquí son variables integradas establecidas por el shell, bash en este ejemplo. El $0 contiene el nombre del script y $@ contiene todos los arguments de línea de command pasados ​​al script, citados individualmente. getopt procesará los arguments de acuerdo con las opciones especificadas. En este ejemplo, getopt reconocerá las opciones largas --run y --rerun sin arguments. Gracias a la opción -a , getopt también reconocerá las forms -run y -rerun . El resultado de la invocación getopt es una list ampliada de arguments. Por ejemplo, una invocación de script como test.sh -run username password se expande por el shell a getopt invocation getopt -a -l run -l rerun -- "test.sh" "-run" "username" "password" . getopt a su vez generará los arguments expandidos --run -- 'username' 'password' .


 if [ $? != 0 ] # There was an error parsing the options then exit 1 fi 

La variable incorporada $? contiene el valor de retorno del command ejecutado más recientemente. Un valor de retorno distinto de cero indica que getopt encontró un error.


 eval set -- "$OPTS" 

Esto esencialmente replaceá los arguments originales de línea de command pasados ​​al script con los arguments expandidos getopt por getopt .


 while true; do case "$1" in --run) echo "option --run specified"; shift;; --rerun) echo "option --rerun specified"; shift;; --) shift; break;; esac done 

El ciclo procesará cada parámetro posicional por turnos, comenzando con el $1 , el primero. Después de la expansión getopt , solo hay tres casos para considerar. Al final del procesamiento, cada shift caso shift los parameters posicionales de modo que $2 convierta en $1 , $3 en $2 y así sucesivamente. Debido a esto, el parámetro posicional $1 tendrá un nuevo valor en cada iteración del ciclo.

Si la opción que se está procesando tomaría un argumento requerido, se podría acceder al valor del argumento en la statement de case través del parámetro posicional $2 . Cuando la opción y su argumento hayan sido procesados, el parámetro posicional deberá cambiarse por 2 para eliminar tanto la opción como el argumento.

A medida que getopt genera a -- después de las opciones reconocidas, antes de los arguments restantes, el -- caso indica el final de la list de opciones y la condición de terminación del ciclo while.


 echo "Args:" for arg # Process remaining arguments do echo $arg done 

for arg es la abreviatura de for arg in "$@" . Tenga en count que después del ciclo while, debido al shift en cada caso, $@ ahora solo contiene los arguments restantes que siguieron -- en la salida de getopt .