¿Desea que sus scripts de shell de Linux manejen las opciones y los argumentos de la línea de comandos con más gracia? El Bash getopts
incorporado le permite analizar las opciones de la línea de comandos con delicadeza, y también es fácil. Te mostramos cómo.
Pasar valores a un script Bash es bastante sencillo. Llama a su secuencia de comandos desde la línea de comando o desde otra secuencia de comandos y proporciona su lista de valores detrás del nombre de la secuencia de comandos. Se puede acceder a estos valores dentro de su secuencia de comandos como variables , comenzando con $1
la primera variable, $2
la segunda y así sucesivamente.
Pero si desea pasar opciones a un script, la situación rápidamente se vuelve más compleja. Cuando decimos opciones, nos referimos a las opciones, banderas o interruptores que ls
pueden manejar programas similares. Están precedidos por un guión “ -
” y generalmente actúan como un indicador para que el programa active o desactive algún aspecto de su funcionalidad.
El ls
comando tiene más de 50 opciones, principalmente relacionadas con el formato de su salida. La -X
opción (ordenar por extensión) ordena la salida alfabéticamente por extensión de archivo . La -U
opción (sin clasificar) enumera por orden de directorio .
Las opciones son solo eso, son opcionales. No sabe qué opciones, si las hay, elegirá usar el usuario, y tampoco sabe en qué orden puede enumerarlas en la línea de comando . Esto aumenta la complejidad del código necesario para analizar las opciones.
Las cosas se vuelven aún más complicadas si algunas de sus opciones toman un argumento, conocido como argumento de opción . Por ejemplo, la ls -w
opción (ancho) espera ser seguida por un número, que representa el ancho máximo de visualización de la salida. Y, por supuesto, es posible que esté pasando otros parámetros a su secuencia de comandos que son simplemente valores de datos, que no son opciones en absoluto.
Afortunadamente getopts
maneja esta complejidad por ti. Y debido a que está integrado, está disponible en todos los sistemas que tienen el shell Bash, por lo que no hay nada que instalar.
Hay una utilidad más antigua llamada getopt
. Este es un pequeño programa de utilidad , no un incorporado. Hay muchas versiones diferentes de getopt
con diferentes comportamientos, mientras que el getops
incorporado sigue las pautas de POSIX.
escriba getopts
escriba getopt
Debido getopt
a que no es una función integrada, no comparte algunos de los beneficios automáticos que getopts
sí tiene, como el manejo sensato de los espacios en blanco . Con getopts
, el shell Bash está ejecutando su secuencia de comandos y el shell Bash está realizando el análisis de opciones. No necesita invocar un programa externo para manejar el análisis.
La compensación es getopts
que no maneja nombres de opciones de formato largo con guiones dobles. Por lo tanto, puede usar opciones formateadas como -w
pero no «» ---wide-format
. Por otro lado, si tiene un script que acepta las opciones -a
, -b
y
, -c
getopts
le permite combinarlas como -abc
, -bca
o -bac
y así sucesivamente.
Estamos discutiendo y demostrando getopts
en este artículo, así que asegúrese de agregar la «s» final al nombre del comando.
Este script no usa opciones discontinuas como -a
o -b
. Acepta parámetros «normales» en la línea de comandos y se accede a ellos dentro del script como valores.
#!/bin/bash # obtener las variables una por una echo "Variable Uno: $1" echo "Variable Dos: $2" echo "Variable Tres: $3" # recorrer las variables para var en " $@" haz echo "$ var" hecho
Se accede a los parámetros dentro del script como variables $1
, $2
o $3
.
Copie este texto en un editor y guárdelo como un archivo llamado «variables.sh». Tendremos que hacerlo ejecutable con el chmod
comando . Deberá realizar este paso para todos los scripts que discutimos. Simplemente sustituya el nombre del archivo de script apropiado cada vez.
chmod +x variables.sh
Si ejecutamos nuestro script sin parámetros, obtenemos este resultado.
./variables.sh
No pasamos parámetros, por lo que el script no tiene valores para informar. Proporcionemos algunos parámetros esta vez.
./variables.sh cómo geek
Como era de esperar, las variables $1
, $2
y $3
se han establecido en los valores de los parámetros y los vemos impresos.
Este tipo de manejo de parámetros uno por uno significa que necesitamos saber de antemano cuántos parámetros habrá. Al bucle en la parte inferior del script no le importa cuántos parámetros hay, siempre los recorre todos.
Si proporcionamos un cuarto parámetro, no se asigna a una variable, pero el ciclo aún lo maneja.
./variables.sh cómo geek sitio web
Si ponemos comillas alrededor de dos de las palabras, se tratan como un parámetro.
./variables.sh cómo "ser geek"
Si vamos a necesitar que nuestro script maneje todas las combinaciones de opciones, opciones con argumentos y parámetros de tipo de datos «normales», necesitaremos separar las opciones de los parámetros regulares. Podemos lograr eso colocando todas las opciones, con o sin argumentos, antes de los parámetros regulares.
Pero no corramos antes de que podamos caminar. Veamos el caso más simple para manejar las opciones de la línea de comandos.
Usamos getopts
en un while
bucle. Cada iteración del ciclo funciona en una opción que se pasó al script. En cada caso, la variable OPTION
se establece en la opción identificada por getopts
.
Con cada iteración del bucle, getopts
pasa a la siguiente opción. Cuando no hay más opciones, getopts
regresa false
y while
sale del bucle.
La OPTION
variable se compara con los patrones en cada una de las cláusulas de declaración de caso. Debido a que estamos usando una declaración de caso , no importa en qué orden se proporcionen las opciones en la línea de comando. Cada opción se coloca en la declaración del caso y se activa la cláusula correspondiente.
Las cláusulas individuales en la declaración del caso facilitan la realización de acciones específicas de opciones dentro del script. Por lo general, en una secuencia de comandos del mundo real, establecería una variable en cada cláusula, y estos actuarían como indicadores más adelante en la secuencia de comandos, permitiendo o denegando alguna funcionalidad.
Copie este texto en un editor y guárdelo como un script llamado «options.sh» y hágalo ejecutable.
#!/bin/bash mientras getopts 'abc' OPCIÓN; hacer caso "$OPCIÓN" en a) echo "Opción a usada" ;; B) echo "Opción b usada" ;; C) echo "Opción c usada" ;; ?) echo "Uso: $(nombre base $0) [-a] [-b] [-c]" salida 1 ;; esac hecho
Esta es la línea que define el ciclo while.
mientras getopts 'abc' OPCIÓN; hacer
El getopts
comando va seguido de la cadena de opciones . Esto enumera las letras que vamos a usar como opciones. Solo las letras de esta lista se pueden utilizar como opciones. Entonces, en este caso, -d
no sería válido. Esto quedaría atrapado por la ?)
cláusula porque getopts
devuelve un signo de interrogación “ ?
” para una opción no identificada. Si eso sucede, el uso correcto se imprime en la ventana de la terminal:
echo "Uso: $(nombre base $0) [-a] [-b] [-c]"
Por convención, envolver una opción entre corchetes “ []
” en este tipo de mensaje de uso correcto significa que la opción es opcional. El comando basename elimina cualquier ruta de directorio del nombre del archivo. El nombre del archivo de script se mantiene en los $0
scripts de Bash.
Usemos este script con diferentes combinaciones de líneas de comando.
./opciones.sh -a
./opciones.sh -a -b -c
./opciones.sh -ab -c
./opciones.sh -taxi
Como podemos ver, todas nuestras combinaciones de prueba de opciones se analizan y manejan correctamente. ¿Y si probamos una opción que no existe?
./opciones.sh -d
Se activa la cláusula de uso, lo cual es bueno, pero también recibimos un mensaje de error del shell. Eso podría o no ser importante para su caso de uso. Si está llamando al script desde otro script que tiene que analizar mensajes de error, será más difícil si el shell también genera mensajes de error.
Desactivar los mensajes de error del shell es muy fácil. Todo lo que tenemos que hacer es poner dos puntos ” :
” como el primer carácter de la cadena de opciones.
Edite su archivo «options.sh» y agregue dos puntos como el primer carácter de la cadena de opciones, o guarde este script como «options2.sh» y hágalo ejecutable.
#!/bin/bash mientras que getopts ':abc' OPCIÓN; hacer caso "$OPCIÓN" en a) echo "Opción a usada" ;; B) echo "Opción b usada" ;; C) echo "Opción c usada" ;; ?) echo "Uso: $(nombre base $0) [-a] [-b] [-c]" salida 1 ;; esac hecho
Cuando ejecutamos esto y generamos un error, recibimos nuestros propios mensajes de error sin ningún mensaje de shell.
./opciones2.sh.sh -d
Para saber getopts
que una opción será seguida por un argumento, coloque dos puntos ” :
” inmediatamente detrás de la letra de la opción en la cadena de opciones.
Si seguimos la «b» y la «c» en nuestra cadena de opciones con dos puntos, getopt
esperará argumentos para estas opciones. Copie este script en su editor y guárdelo como «arguments.sh», y hágalo ejecutable.
Recuerde, los primeros dos puntos en la cadena de opciones se usan para suprimir los mensajes de error del shell; no tiene nada que ver con el procesamiento de argumentos.
Cuando getopt
procesa una opción con un argumento, el argumento se coloca en la OPTARG
variable. Si desea utilizar este valor en otra parte de su secuencia de comandos, deberá copiarlo en otra variable.
#!/bin/bash while getopts ':ab:c:' OPCIÓN; hacer caso "$OPCIÓN" en a) echo "Opción a usada" ;; B) argB="$OPTARG" echo "Opción b usada con: $argB" ;; C) argC="$OPTARG" echo "Opción c usada con: $argC" ;; ?) echo "Uso: $(nombre base $0) [-a] [-b argumento] [-c argumento]" salida 1 ;; esac hecho
Vamos a ejecutar eso y ver cómo funciona.
./argumentos.sh -a -b "cómo ser geek" -c reviewgeek
./argumentos.sh -c reviewgeek -a
Así que ahora podemos manejar opciones con o sin argumentos, independientemente del orden en que se presenten en la línea de comandos.
Pero, ¿qué pasa con los parámetros regulares? Anteriormente dijimos que sabíamos que tendríamos que ponerlos en la línea de comando después de cualquier opción. A ver qué pasa si lo hacemos.
Cambiaremos nuestro script anterior para incluir una línea más. Cuando el while
ciclo haya salido y todas las opciones hayan sido manejadas, intentaremos acceder a los parámetros regulares. Imprimiremos el valor en $1
.
Guarde este script como «arguments2.sh» y hágalo ejecutable.
#!/bin/bash while getopts ':ab:c:' OPCIÓN; hacer caso "$OPCIÓN" en a) echo "Opción a usada" ;; B) argB="$OPTARG" echo "Opción b usada con: $argB" ;; C) argC="$OPTARG" echo "Opción c usada con: $argC" ;; ?) echo "Uso: $(nombre base $0) [-a] [-b argumento] [-c argumento]" salida 1 ;; esac hecho echo "La variable uno es: $1"
Ahora probaremos algunas combinaciones de opciones y parámetros.
./argumentos2.sh dave
./argumentos2.sh -a dave
./argumentos2.sh -a -c cómo-ser-geek dave
Así que ahora podemos ver el problema. Tan pronto como se utilizan las opciones, las variables $1
en adelante se rellenan con los indicadores de opciones y sus argumentos. En el último ejemplo, $4
mantendría el valor del parámetro «dave», pero ¿cómo accede a eso en su secuencia de comandos si no sabe cuántas opciones y argumentos se van a usar?
La respuesta es usar OPTIND
y el shift
comando.
El shift
comando descarta el primer parámetro, independientemente del tipo, de la lista de parámetros. Los otros parámetros se “rebajan aleatoriamente”, por lo que el parámetro 2 se convierte en el parámetro 1, el parámetro 3 se convierte en el parámetro 2, y así sucesivamente. Y así $2
se vuelve $1
, $3
se vuelve $2
, y así sucesivamente.
Si proporciona shift
un número, eliminará esa cantidad de parámetros de la lista.
OPTIND
cuenta las opciones y los argumentos a medida que se encuentran y procesan. Una vez que se hayan procesado todas las opciones y argumentos, OPTIND
será uno más que el número de opciones. Entonces, si usamos shift para recortar (OPTIND-1)
parámetros de la lista de parámetros, nos quedaremos con los parámetros regulares en $1
adelante.
Eso es exactamente lo que hace este script. Guarde este script como «arguments3.sh» y hágalo ejecutable.
#!/bin/bash while getopts ':ab:c:' OPCIÓN; hacer caso "$OPCIÓN" en a) echo "Opción a usada" ;; B) argB="$OPTARG" echo "Opción b usada con: $argB" ;; C) argC="$OPTARG" echo "Opción c usada con: $argC" ;; ?) echo "Uso: $(nombre base $0) [-a] [-b argumento] [-c argumento]" salida 1 ;; esac hecho echo "Antes - la variable uno es: $1" cambio "$(($OPTIND -1))" echo "Después - la variable uno es: $1" echo "El resto de los argumentos (operandos)" para x en "$@" hacer eco $x hecho
Lo ejecutaremos con una combinación de opciones, argumentos y parámetros.
./arguments3.sh -a -c how-to-geek "dave dee" dozy beaky mick tich
Podemos ver que antes de llamar a shift
, $1
mantuvimos «-a», pero después de que el comando shift $1
mantiene nuestro primer parámetro sin opción ni argumento. Podemos recorrer todos los parámetros tan fácilmente como en un script sin análisis de opciones.
El manejo de opciones y sus argumentos en scripts no tiene por qué ser complicado. Con getopts
usted puede crear secuencias de comandos que manejen opciones, argumentos y parámetros de la línea de comandos exactamente como deberían hacerlo las secuencias de comandos nativas compatibles con POSIX.
El mundo del gaming ha experimentado un crecimiento exponencial en los últimos años. La…
Stokkete/Shutterstock.com ¿Sigue utilizando una unidad flash USB obsoleta para almacenar sus archivos? ¿Por qué no…
LG Los fabricantes siempre intentan mejorar el rendimiento de imagen de los monitores. Como resultado,…
Patty Chan/Shutterstock.com Si cree en lo que ve en las redes sociales, puede pensar en…
Seksan.TH/Shutterstock.com Los servicios de suscripción como Netflix, Game Pass y Spotify nos permiten consumir tantas…
fatmawati achmad zaenuri/Shutterstock El acceso a Internet, oa cualquier otra red, se rige por la…