Menú
Está libre
registro
hogar  /  Programas/ Argumentos Bash. Funciones bash en scripts

Bash argumentos. Funciones bash en scripts

Habiendo dominado las partes anteriores de esta serie, aprendió qué son los scripts bash, cómo escribirlos, cómo controlar el flujo de un programa y cómo trabajar con archivos. Hoy hablaremos sobre cómo agregar interactividad a los scripts, dotándolos de la capacidad de recibir datos del usuario y procesarlos.

La forma más común de pasar datos a los scripts es mediante el uso de parámetros de línea de comandos. Al llamar al script con parámetros, le pasamos información con la que puede funcionar. Se parece a esto:

$ ./myscript 10 20
En este ejemplo, al script se le pasan dos parámetros: "10" y "20". Todo esto está bien, pero ¿cómo lee los datos en el guión?

Leer parámetros de línea de comando

El shell bash asigna parámetros de línea de comando ingresados ​​al invocar el script a variables especiales llamadas parámetros posicionales:
  • $ 0 es el nombre del script.
  • $ 1 es el primer parámetro.
  • $ 2 es el segundo parámetro, y así sucesivamente, hasta la variable $ 9, que contiene el noveno parámetro.
A continuación, le mostramos cómo puede utilizar los parámetros de la línea de comandos en un script utilizando estas variables:

#! / bin / bash echo $ 0 echo $ 1 echo $ 2 echo $ 3
Ejecutemos el script con parámetros:

./myscript 5 10 15
Esto es lo que generará en la consola.


Visualización de los parámetros con los que se ejecuta el script

Tenga en cuenta que los parámetros de la línea de comandos están separados por espacios.

Echemos un vistazo a otro ejemplo de uso de parámetros. Aquí encontraremos la suma de los números pasados ​​al script:

#! / bin / bash total = $ [$ 1 + $ 2] echo El primer parámetro es $ 1. echo El segundo parámetro es $ 2. echo La suma es $ total.
Ejecutemos el script y verifiquemos el resultado del cálculo.


Un script que encuentra la suma de los números que se le pasan.

Los parámetros de la línea de comandos no tienen por qué ser números. También puede pasar cadenas a los scripts. Por ejemplo, aquí hay una secuencia de comandos que funciona con una cadena:

#! / bin / bash echo Hola $ 1, ¿cómo estás?
Ejecútelo:

./myscript Adam
Producirá lo que esperamos de él.


Script que funciona con un parámetro de cadena

¿Qué pasa si el parámetro contiene espacios y necesitamos procesarlo como un dato independiente? Suponemos que si domina las partes anteriores de esta guía, ya conoce la respuesta. Consiste en el uso de comillas.

Si el script necesita más de nueve parámetros, al referirse a ellos, el número en el nombre de la variable debe ir entre llaves, por ejemplo:

Verificación de parámetros

Si se llama al script sin parámetros, pero para el funcionamiento normal del código se supone que existen, se producirá un error. Por lo tanto, se recomienda verificar siempre la presencia de parámetros pasados ​​al script cuando se llama. Por ejemplo, se puede organizar así:

#! / bin / bash if [-n "$ 1"] entonces echo Hola $ 1. else echo "No se encontraron parámetros". fi
Llamemos al script primero con un parámetro y luego sin parámetros.


Llamar a un script que comprueba los parámetros de la línea de comandos

Contando parámetros

En el script, puede contar el número de parámetros que se le pasan. El shell bash proporciona una variable especial para esto. Es decir, la variable $ # contiene el número de parámetros pasados ​​al script cuando se llama.

Probémoslo:

#! / bin / bash echo Se pasaron $ # parámetros.
Llamemos al guión.

./myscript 1 2 3 4 5
Como resultado, el script informará que se le han pasado 5 parámetros.


Contando el número de parámetros en el script

Esta variable proporciona una forma inusual de obtener el último de los parámetros pasados ​​al script, que no requiere conocer su número. Así es como se ve:

#! / bin / bash echo El último parámetro fue $ (! #)
Llamemos al script y veamos qué produce.


Refiriéndose al último parámetro

Capturando todas las opciones de la línea de comando

En algunos casos, es necesario capturar todos los parámetros pasados ​​al script. Para hacer esto, puede usar las variables $ * y [correo electrónico protegido]... Ambos contienen todos los parámetros de la línea de comandos, lo que permite acceder a lo que se pasa al script sin utilizar parámetros posicionales.

La variable $ * contiene todos los parámetros ingresados ​​en la línea de comando como una sola "palabra".

En una variable [correo electrónico protegido] los parámetros se dividen en "palabras" independientes. Estos parámetros se pueden iterar en bucles.

Veamos la diferencia entre estas variables con ejemplos. Primero echemos un vistazo a su contenido:

#! / bin / bash echo "Usando el método \ $ *: $ *" echo "-----------" echo "Usando el \ [correo electrónico protegido] método: [correo electrónico protegido]"
Aquí está la salida del script.


Variables $ * y [correo electrónico protegido]

Como puede ver, la salida de ambas variables es la misma. Ahora intentemos revisar el contenido de estas variables en bucles para ver la diferencia entre ellas:

#! / bin / bash count = 1 para param en "$ *" do echo "\ $ * Parameter # $ count = $ param" count = $ (($ count + 1)) done count = 1 para param in " [correo electrónico protegido]"haz eco" \ [correo electrónico protegido] Parámetro # $ count = $ param "count = $ (($ count + 1)) hecho
Eche un vistazo a lo que genera el script en la consola. La diferencia entre las variables es bastante obvia.


Analizando $ * y [correo electrónico protegido] en un bucle

La variable $ * contiene todos los parámetros pasados ​​al script como un solo dato, mientras que en la variable [correo electrónico protegido] están representados por significados independientes. Qué variable usar depende de qué se necesita exactamente en un escenario particular.

Comando de cambio

Utilice el comando shift en scripts bash con precaución, ya que literalmente cambia los valores de los parámetros posicionales.

Cuando usa este comando, cambia los valores de los parámetros posicionales a la izquierda de forma predeterminada. Por ejemplo, el valor de la variable $ 3 se convierte en el valor de la variable $ 2, el valor de $ 2 se convierte en $ 1 y lo que antes estaba en $ 1 se pierde. Tenga en cuenta que esto no cambia el valor de la variable $ 0 que contiene el nombre del script.

Usando el comando shift, veamos otra forma de iterar sobre los parámetros pasados ​​al script:

#! / bin / bash count = 1 while [-n "$ 1"] do echo "Parámetro # $ count = $ 1" count = $ (($ count + 1)) shift done
El script usa un bucle while, verificando la longitud del valor del primer parámetro. Cuando la longitud se vuelve cero, se sale del bucle. Después de verificar el primer parámetro y mostrarlo en la pantalla, se llama al comando de cambio, que cambia los valores del parámetro en una posición.


Usando el comando shift para iterar sobre los parámetros

Cuando utilice el comando shift, recuerde que cada vez que lo llame, el valor de la variable $ 1 se perderá irremediablemente.

Conmutadores de línea de comando

Los interruptores de la línea de comandos suelen aparecer como letras precedidas por un guión. Se utilizan para administrar scripts. Considere este ejemplo:

#! / bin / bash echo while [-n "$ 1"] do case "$ 1" en -a) echo "Encontré la opción -a" ;; -b) echo "Encontré la opción -b" ;; -c) echo "Encontré la opción -c" ;; *) echo "$ 1 no es una opción" ;; esac turno hecho
Ejecutemos el script:

$ ./myscript –a –b –c –d
Y analicemos lo que muestra en la terminal.


Manejo de claves en script

Este código usa la construcción del caso, que compara la clave pasada con la lista de claves procesadas por el script. Si el valor pasado se encuentra en esta lista, se ejecuta la rama de código correspondiente. Si, al llamar al script, se utiliza cualquier clave, cuyo procesamiento no se proporciona, se ejecutará la rama "*".

Cómo distinguir entre claves y parámetros

A menudo, al escribir scripts bash, surge una situación en la que necesita usar tanto parámetros de línea de comandos como conmutadores. La forma estándar de hacer esto es usar una secuencia de caracteres especial que le dice al script cuándo terminan las teclas y comienzan los parámetros normales.

Esta secuencia es un guión doble (-). El shell lo usa para indicar la posición en la que termina la lista de claves. Una vez que el script detecta el signo del final de las claves, lo que queda puede, sin temor a errores, procesarse como parámetros y no como claves. Consideremos un ejemplo:

#! / bin / bash while [-n "$ 1"] do case "$ 1" en -a) echo "Encontré la opción -a" ;; -b) echo "Encontré la opción -b" ;; -c) echo "Encontré la opción -c" ;; -) cambio de turno ;; *) echo "$ 1 no es una opción" ;; esac shift done count = 1 para el parámetro en [correo electrónico protegido] do echo "Parameter # $ count: $ param" count = $ (($ count + 1)) done
Este script usa el comando break para interrumpir el ciclo while si encuentra un guión doble en la línea.

Esto es lo que obtienes después de llamarlo.


Manejo de parámetros y parámetros de la línea de comandos

Como puede ver, cuando el script, al analizar los datos que se le pasan, encuentra un guión doble, termina de procesar las claves y considera como parámetros todo lo que aún no ha sido procesado.

Manejo de claves con valores

A medida que sus scripts se vuelven más complejos, se enfrentará a situaciones en las que las claves normales ya no son suficientes, lo que significa que deberá utilizar claves con determinados valores. Por ejemplo, una llamada de secuencia de comandos que utiliza esta función se ve así:

./myscript -a prueba1 -b -c prueba2
El script debe poder determinar cuándo se utilizan parámetros adicionales junto con los modificadores de la línea de comandos:

#! / bin / bash while [-n "$ 1"] do case "$ 1" en -a) echo "Encontré la opción -a" ;; -b) param = "$ 2" echo "Se encontró la opción -b, con el valor del parámetro $ param" shift ;; -c) echo "Encontré la opción -c" ;; -) cambio de turno ;; *) echo "$ 1 no es una opción" ;; esac shift done count = 1 for param in " [correo electrónico protegido]"do echo" Parámetro # $ count: $ param "count = $ (($ count + 1)) hecho
Llamemos a este script así:

./myscript -a -b test1 -d
Veamos los resultados de su trabajo.


Manejo de parámetros clave

En este ejemplo, se procesan tres claves en la construcción del caso. El modificador -b requiere un parámetro adicional. Dado que la clave que se está procesando está en la variable $ 1, su parámetro correspondiente estará en $ 2 (el comando de cambio se usa aquí, por lo tanto, a medida que avanza el procesamiento, todo lo que se pasa al script se desplaza hacia la izquierda). Cuando nos dimos cuenta de esto, solo queda extraer el valor de la variable $ 2 y tendremos el parámetro de la clave requerida. Por supuesto, aquí se necesita un comando de cambio más para que la siguiente tecla entre en $ 1.

Usando llaves estándar

Al escribir scripts de bash, puede elegir cualquier letra para las teclas de la línea de comando y establecer arbitrariamente la reacción del script a estas teclas. Sin embargo, en el mundo de Linux, algunos valores clave se han convertido en una especie de estándar que es útil cumplir. Aquí hay una lista de estas claves:
-a Muestra todos los objetos.
-c Realizar recuento.
-d Especifica el directorio.
-e Expande el objeto.
-f Especifica el archivo desde el que leer los datos.
-h Muestra la ayuda para el comando.
-i Ignorar el caso.
-l Realiza una salida de formato completo.
-n Utiliza el modo no interactivo (por lotes).
-o Le permite especificar el archivo al que desea redirigir la salida.
-q Ejecuta el script en modo silencioso.
-r Procesar carpetas y archivos de forma recursiva.
-s Ejecuta el script en modo silencioso.
-v Ejecuta una salida detallada.
-x Excluir objeto.
-y Responda sí a todas las preguntas.

Si está en Linux, probablemente esté familiarizado con muchas de estas claves. Utilizándolos en su significado generalmente aceptado en sus scripts, puede ayudar a los usuarios a interactuar con ellos sin tener que preocuparse por leer la documentación.

Recibir datos del usuario

Los interruptores y parámetros de la línea de comandos son una excelente manera de obtener datos del usuario del script, pero en algunos casos se necesita más interactividad.

A veces, los scripts necesitan datos que el usuario debe ingresar durante la ejecución del programa. El shell bash proporciona un comando de lectura para este mismo propósito.

Este comando le permite aceptar la entrada de una entrada estándar (teclado) u otros descriptores de archivo. Después de recibir los datos, este comando los coloca en una variable:

#! / bin / bash echo -n "Ingresa tu nombre:" lee el nombre echo "Hola $ nombre, bienvenido a mi programa".
Tenga en cuenta que el comando echo, que muestra el indicador, se invoca con la opción -n. Esto da como resultado que no se muestre ningún avance de línea al final del mensaje, lo que permite al usuario del script ingresar datos donde aparece el mensaje en lugar de en la siguiente línea.


Manejo de la entrada del usuario

Se pueden especificar varias variables al llamar a read:

#! / bin / bash read -p "Ingrese su nombre:" primer último eco "Sus datos para $ último, $ primero ..."
Esto es lo que generará el script después del lanzamiento.


Varias variables en el comando de lectura

Si no especifica una variable llamando a read, los datos ingresados ​​por el usuario se colocarán en la variable de entorno especial REPLY:

#! / bin / bash read -p "Ingresa tu nombre:" echo Hola $ REPLY, bienvenido a mi programa.


Usando la variable de entorno REPLY

Si el script debe continuar la ejecución independientemente de si el usuario ingresa algunos datos o no, llamando al comando de lectura, puede usar el modificador -t. A saber, el parámetro clave establece el tiempo de espera para la entrada en segundos:

#! / bin / bash if read -t 5 -p "Ingresa tu nombre:" nombre y luego echo "Hola $ nombre, bienvenido a mi script" else echo "¡Lo siento, demasiado lento!" fi
Si los datos no se ingresan en 5 segundos, el script ejecutará la rama de la declaración condicional else, generando una disculpa.


Límite de tiempo para la entrada de datos

Ingresando contraseñas

A veces es mejor no mostrar lo que el usuario ingresa en respuesta a una pregunta del guión. Por ejemplo, esto se suele hacer cuando se solicitan contraseñas. El interruptor -s al comando de lectura evita que la entrada del teclado se muestre en la pantalla. De hecho, los datos se emiten, pero el comando de lectura hace que el color del texto sea el mismo que el color de fondo.

#! / bin / bash read -s -p "Ingrese su contraseña:" pass echo "¿Es su contraseña realmente $ pass?"
Así es como funcionará este script.


Ingresando datos confidenciales

Leer datos de un archivo

El comando de lectura puede, en cada invocación, leer una línea de texto de un archivo. Cuando no haya más líneas sin leer en el archivo, simplemente se detendrá. Si necesita obtener todo el contenido de un archivo en un script, puede, usando una canalización, transferir los resultados de llamar al comando cat para el archivo, la construcción while, que contiene el comando read (por supuesto, usando el comando cat El comando parece primitivo, pero nuestro objetivo es mostrar todo de la manera más simple posible, enfocándonos en los novatos; los usuarios experimentados seguramente lo entenderán).

Escribamos un script que use el enfoque para leer archivos que se acaba de describir.

#! / bin / bash count = 1 cat miarchivo | while read line do echo "Line $ count: $ line" count = $ (($ count + 1)) done echo "Finished"
Veámoslo en acción.


Leer datos de un archivo

Aquí pasamos el contenido del archivo al ciclo while y revisamos todas las líneas de este archivo, mostrando el número y contenido de cada uno de ellos.

Resultados

Hoy hemos examinado cómo trabajar con interruptores y parámetros de línea de comando. Sin estas herramientas, el rango de uso de los scripts es extremadamente limitado. Incluso si el guión está escrito, como dicen, "para mí". Aquí examinamos los enfoques para recibir datos del usuario durante la ejecución del programa; esto hace que los scripts sean interactivos.

La próxima vez, hablemos de las operaciones de entrada y salida.

¡Queridos lectores! Gracias por compartir su experiencia en los comentarios a las partes anteriores de esta serie de materiales. Si tienes algo que decir sobre el procesamiento de todo lo que se puede pasar al script en el inicio o mientras se está ejecutando, estamos seguros de que a muchos les interesará leer al respecto.

Probablemente todo el mundo sepa que el shell Bash tiene comandos integrados que no están en las carpetas / bin o / usr / bin. Están integrados en el shell y se ejecutan como funciones. En un artículo anterior, miramos. Discutimos casi todo allí, cómo deberían verse los scripts, el uso de condiciones, bucles, variables, pero no nos detuvimos en las funciones.

En el artículo de hoy, arreglaremos esta falla. Al igual que con cualquier lenguaje de programación, Bash tiene funciones que pueden ser muy útiles de usar. Veremos el uso de funciones bash, cómo escribirlas e incluso cómo crear bibliotecas a partir de estas funciones.

Primero, debe comprender qué es una función en nuestro contexto. Una función es una colección de comandos, unidos por un nombre, que realizan una tarea específica. La función se llama por su nombre, puede tomar parámetros y devolver el resultado de su trabajo. En resumen, las funciones de Bash funcionan igual que en otros lenguajes de programación.

La sintaxis para crear una función es muy simple:

nombre_función () (lista_comando)

El nombre de la función no debe coincidir con ninguno de los comandos o funciones existentes, y todos los comandos del cuerpo de la función se escriben en una nueva línea.

Función simple

Escribamos una pequeña función que imprimirá una cadena en la pantalla:

$ vi function.sh

#! / bin / bash
printtr () (
echo "hola mundo"
}
printtr

La llamada a una función bash se realiza especificando su nombre, como cualquier otro comando. Ejecute nuestro script para su ejecución, no olvide que antes debe otorgarle permisos de ejecución:

chmod u + x function.sh

Todo funciona, ahora compliquemos la tarea, intentemos pasar argumentos a la función.

Argumentos de función

Los argumentos de la función deben pasarse cuando se llaman, y se leen de la misma forma que los argumentos del script. La sintaxis para llamar a una función con parámetros bash es:

nombre de la función arg1 arg2 ... argN

Como ves, todo es bastante sencillo. Los parámetros están separados por un espacio. Ahora mejoremos nuestra función para generar la cadena que especificamos:

! / bin / bash
printtr () (
echo $ 1
}
printtr "Hola mundo"

Puedes hacer varios parámetros:

! / bin / bash
printtr () (
echo $ 1
echo $ 2
echo $ 3
echo $ 5
}
printtr "arg1" "arg2" "arg3" "arg4" "arg5"

Hay otra forma de completar argumentos, como en C, usando la pila. Sacamos el primer argumento, luego cambiamos el puntero de la pila de argumentos en uno y volvemos a sacar el primer argumento. Etc:

! / bin / bash
printtr () (
echo $ 1
cambio
echo $ 1
cambio
echo $ 1
cambio
echo $ 1
}
imprimetr "arg1" "arg2" "arg3" "arg4"

Devolver el resultado de una función

No solo puede usar funciones con parámetros bash, sino también obtener el resultado de su trabajo. Para hacer esto, use el comando return. Termina la función y devuelve el valor numérico del código de retorno. Puede ser de 0 a 255:

! / bin / bash
printtr () (
return 134;
}
printtr
echo $?

Si necesita aplicar un valor de retorno de función bash en lugar de un código de estado, use echo. La cadena no se envía inmediatamente al terminal, sino que se devuelve como resultado de la función y se puede escribir en una variable y luego usar:

! / bin / bash
printtr () (
echo "prueba"
}
VAR = $ (imprimetr)
echo $ VAR

Funciones de exportación

Puede hacer que una función esté disponible fuera del script con el comando declare:

! / bin / bash
printtr () (
echo "hola mundo"
}
declarar -x -f printstr

Luego ejecute el script usando el comando fuente:

función fuente.sh
$ printstr

Recursividad

Puede llamar a una función desde sí misma para hacer la recursividad:

! / bin / bash
printtr () (
echo "hola mundo"
printtr
}
printtr

Puede experimentar con la recursividad, puede ser útil en muchos casos, solo recuerde hacer la primera llamada a la función Bash.

Variables locales en una función

Si declara una variable ordinaria en una función, estará disponible en todo el script, esto es conveniente para devolver el valor de una función, pero a veces es posible que necesite crear una variable local. Hay un comando local para esto:

! / bin / bash
printtr () (
VAR local = $ 1
echo $ (VAR)
}
printtr "Hola mundo"

Bibliotecas de funciones

Podemos tomar algunas funciones de bash y combinarlas en una biblioteca para que podamos importar esas funciones con un comando. Esto se hace de forma similar a la exportación de funciones. Primero, creemos un archivo de biblioteca:

prueba1 () (
echo "Hola mundo desde 1";
}
prueba2 () (
echo "Hola mundo desde 2";
}
prueba3 () (
echo "Hola mundo desde 3";
}

Ahora creemos un script que usará nuestras funciones. Puede importar la biblioteca usando el comando de origen o simplemente especificando el nombre del script:

! / bin / bash
fuente lib.sh
test1
test2
test3

conclusiones

En este artículo, analizamos las funciones de bash, cómo escribirlas, usarlas y agruparlas en bibliotecas. Si a menudo escribe scripts en Bash, esta información le será útil. Puedes crear tu propio conjunto de funciones para usarlas en cada script y así facilitar tu trabajo.

Creé un script con magia getopt estándar, por lo que puede llamar al script con

Batman-conecta -c ffki

¿Cómo agrego un parámetro para llamar a este script con un solo parámetro sin un guión?

batman-connect ffki

por lo que interpretará esa única opción como el segundo argumento de -c?

De acuerdo con esta respuesta, probé:

Si [ [correo electrónico protegido]= "ffki"]; luego establece - "-c [correo electrónico protegido]"fi

Pero esto conduce a un error, creo, porque esta línea en mi script lo cambiará:

# Ejecutar getopt sobre los argumentos pasados ​​a este programa, identificados por el carácter especial [correo electrónico protegido] PARSED_OPTIONS = $ (getopt -n "$ 0" -o hsrvVi: c: --long "ayuda, iniciar, reiniciar, detener, detallado, vv, versión, interfaz :, comunidad:" - " [correo electrónico protegido]")

No me gusta reinstalar todo mi script, entonces, ¿hay una línea simple para establecer el primer argumento en "-c" y el segundo en "ffki"?

4 Las soluciones recopilan el formulario web para "Cambiar los argumentos de bash si solo se proporciona un argumento"

Puedes hacer algo como

Si [$ # = 1]; luego # haz lo que sea que hagas cuando solo haya un argumento, de lo contrario # haz los bits getopt fi # haz lo que harías en cualquier caso

Si -c es el único conmutador que desea admitir, entonces no necesita getopt y puede hacer algo como esto en su lugar:

#! / bin / bash uso () (echo "Uso: $ 0 [-c] arg"> & 2 salir 1) if [$ # = 2]; entonces si [$ 1 = "-c"]; luego cambie c_switch_value = "$ 1", de lo contrario, use fi elif [$ # = 1]; entonces c_switch_value = "$ 1" más el uso fi

Sin embargo, si esto es más legible es discutible.

Si [$ # = 1]; entonces # Si solo hay un argumento, reemplace el proceso actual con la nueva invocación del script # la única opción se usará como -c opción exec "$ 0" -c " [correo electrónico protegido]"fi

Esto no responde a la pregunta original, pero es una solución que funciona en mi caso especial.

El comando en la cláusula if se expande a [seguido de una lista de extensiones de sustitución de palabras que componen los siguientes parámetros posicionales con las palabras = ffki]. En términos generales, $ VAR no significa "valor VAR" cuando está fuera de las comillas dobles, significa "dividir el valor VAR en palabras separadas e interpretarlas como globos". Consulte ¿Por qué mi script de shell se ahoga con espacios u otros caracteres especiales?

Además, " [correo electrónico protegido]"Es un caso especial: se expande a una lista de parámetros posicionales (sin expansión adicional), ni una sola palabra (a pesar de las comillas). Puede usar" $ * ", que se expande a una sola palabra de parámetros posicionales, separados por un espacio (más precisamente, el primer carácter del valor IFS) Entonces, para verificar si hay un parámetro posicional cuyo valor es ffki, puede usar

Si ["$ *" = "ffki"]; luego

Si [$ # -eq 1] && ["$ 1" = "ffki"]; luego

Para cambiar los parámetros de posición que estaba cerca: use el conjunto incorporado y pase el nuevo conjunto de parámetros de posición como argumentos separados. Si existe el riesgo de que el primer parámetro comience con un -, use set -… para que no se interprete como una opción.

Si ["$ *" = "ffki"]; luego establece - -c "ffki" fi

Habiendo dominado las partes anteriores de esta serie, aprendió qué son los scripts bash, cómo escribirlos, cómo controlar el flujo de un programa y cómo trabajar con archivos. Hoy hablaremos sobre cómo agregar interactividad a los scripts, dotándolos de la capacidad de recibir datos del usuario y procesarlos.

La forma más común de pasar datos a los scripts es mediante el uso de parámetros de línea de comandos. Al llamar al script con parámetros, le pasamos información con la que puede funcionar. Se parece a esto:

$ ./myscript 10 20
En este ejemplo, al script se le pasan dos parámetros: "10" y "20". Todo esto está bien, pero ¿cómo lee los datos en el guión?

Leer parámetros de línea de comando

El shell bash asigna parámetros de línea de comando ingresados ​​al invocar el script a variables especiales llamadas parámetros posicionales:
  • $ 0 es el nombre del script.
  • $ 1 es el primer parámetro.
  • $ 2 es el segundo parámetro, y así sucesivamente, hasta la variable $ 9, que contiene el noveno parámetro.
A continuación, le mostramos cómo puede utilizar los parámetros de la línea de comandos en un script utilizando estas variables:

#! / bin / bash echo $ 0 echo $ 1 echo $ 2 echo $ 3
Ejecutemos el script con parámetros:

./myscript 5 10 15
Esto es lo que generará en la consola.


Visualización de los parámetros con los que se ejecuta el script

Tenga en cuenta que los parámetros de la línea de comandos están separados por espacios.

Echemos un vistazo a otro ejemplo de uso de parámetros. Aquí encontraremos la suma de los números pasados ​​al script:

#! / bin / bash total = $ [$ 1 + $ 2] echo El primer parámetro es $ 1. echo El segundo parámetro es $ 2. echo La suma es $ total.
Ejecutemos el script y verifiquemos el resultado del cálculo.


Un script que encuentra la suma de los números que se le pasan.

Los parámetros de la línea de comandos no tienen por qué ser números. También puede pasar cadenas a los scripts. Por ejemplo, aquí hay una secuencia de comandos que funciona con una cadena:

#! / bin / bash echo Hola $ 1, ¿cómo estás?
Ejecútelo:

./myscript Adam
Producirá lo que esperamos de él.


Script que funciona con un parámetro de cadena

¿Qué pasa si el parámetro contiene espacios y necesitamos procesarlo como un dato independiente? Suponemos que si domina las partes anteriores de esta guía, ya conoce la respuesta. Consiste en el uso de comillas.

Si el script necesita más de nueve parámetros, al referirse a ellos, el número en el nombre de la variable debe ir entre llaves, por ejemplo:

Verificación de parámetros

Si se llama al script sin parámetros, pero para el funcionamiento normal del código se supone que existen, se producirá un error. Por lo tanto, se recomienda verificar siempre la presencia de parámetros pasados ​​al script cuando se llama. Por ejemplo, se puede organizar así:

#! / bin / bash if [-n "$ 1"] entonces echo Hola $ 1. else echo "No se encontraron parámetros". fi
Llamemos al script primero con un parámetro y luego sin parámetros.


Llamar a un script que comprueba los parámetros de la línea de comandos

Contando parámetros

En el script, puede contar el número de parámetros que se le pasan. El shell bash proporciona una variable especial para esto. Es decir, la variable $ # contiene el número de parámetros pasados ​​al script cuando se llama.

Probémoslo:

#! / bin / bash echo Se pasaron $ # parámetros.
Llamemos al guión.

./myscript 1 2 3 4 5
Como resultado, el script informará que se le han pasado 5 parámetros.


Contando el número de parámetros en el script

Esta variable proporciona una forma inusual de obtener el último de los parámetros pasados ​​al script, que no requiere conocer su número. Así es como se ve:

#! / bin / bash echo El último parámetro fue $ (! #)
Llamemos al script y veamos qué produce.


Refiriéndose al último parámetro

Capturando todas las opciones de la línea de comando

En algunos casos, es necesario capturar todos los parámetros pasados ​​al script. Para hacer esto, puede usar las variables $ * y [correo electrónico protegido]... Ambos contienen todos los parámetros de la línea de comandos, lo que permite acceder a lo que se pasa al script sin utilizar parámetros posicionales.

La variable $ * contiene todos los parámetros ingresados ​​en la línea de comando como una sola "palabra".

En una variable [correo electrónico protegido] los parámetros se dividen en "palabras" independientes. Estos parámetros se pueden iterar en bucles.

Veamos la diferencia entre estas variables con ejemplos. Primero echemos un vistazo a su contenido:

#! / bin / bash echo "Usando el método \ $ *: $ *" echo "-----------" echo "Usando el \ [correo electrónico protegido] método: [correo electrónico protegido]"
Aquí está la salida del script.


Variables $ * y [correo electrónico protegido]

Como puede ver, la salida de ambas variables es la misma. Ahora intentemos revisar el contenido de estas variables en bucles para ver la diferencia entre ellas:

#! / bin / bash count = 1 para param en "$ *" do echo "\ $ * Parameter # $ count = $ param" count = $ (($ count + 1)) done count = 1 para param in " [correo electrónico protegido]"haz eco" \ [correo electrónico protegido] Parámetro # $ count = $ param "count = $ (($ count + 1)) hecho
Eche un vistazo a lo que genera el script en la consola. La diferencia entre las variables es bastante obvia.


Analizando $ * y [correo electrónico protegido] en un bucle

La variable $ * contiene todos los parámetros pasados ​​al script como un solo dato, mientras que en la variable [correo electrónico protegido] están representados por significados independientes. Qué variable usar depende de qué se necesita exactamente en un escenario particular.

Comando de cambio

Utilice el comando shift en scripts bash con precaución, ya que literalmente cambia los valores de los parámetros posicionales.

Cuando usa este comando, cambia los valores de los parámetros posicionales a la izquierda de forma predeterminada. Por ejemplo, el valor de la variable $ 3 se convierte en el valor de la variable $ 2, el valor de $ 2 se convierte en $ 1 y lo que antes estaba en $ 1 se pierde. Tenga en cuenta que esto no cambia el valor de la variable $ 0 que contiene el nombre del script.

Usando el comando shift, veamos otra forma de iterar sobre los parámetros pasados ​​al script:

#! / bin / bash count = 1 while [-n "$ 1"] do echo "Parámetro # $ count = $ 1" count = $ (($ count + 1)) shift done
El script usa un bucle while, verificando la longitud del valor del primer parámetro. Cuando la longitud se vuelve cero, se sale del bucle. Después de verificar el primer parámetro y mostrarlo en la pantalla, se llama al comando de cambio, que cambia los valores del parámetro en una posición.


Usando el comando shift para iterar sobre los parámetros

Cuando utilice el comando shift, recuerde que cada vez que lo llame, el valor de la variable $ 1 se perderá irremediablemente.

Conmutadores de línea de comando

Los interruptores de la línea de comandos suelen aparecer como letras precedidas por un guión. Se utilizan para administrar scripts. Considere este ejemplo:

#! / bin / bash echo while [-n "$ 1"] do case "$ 1" en -a) echo "Encontré la opción -a" ;; -b) echo "Encontré la opción -b" ;; -c) echo "Encontré la opción -c" ;; *) echo "$ 1 no es una opción" ;; esac turno hecho
Ejecutemos el script:

$ ./myscript –a –b –c –d
Y analicemos lo que muestra en la terminal.


Manejo de claves en script

Este código usa la construcción del caso, que compara la clave pasada con la lista de claves procesadas por el script. Si el valor pasado se encuentra en esta lista, se ejecuta la rama de código correspondiente. Si, al llamar al script, se utiliza cualquier clave, cuyo procesamiento no se proporciona, se ejecutará la rama "*".

Cómo distinguir entre claves y parámetros

A menudo, al escribir scripts bash, surge una situación en la que necesita usar tanto parámetros de línea de comandos como conmutadores. La forma estándar de hacer esto es usar una secuencia de caracteres especial que le dice al script cuándo terminan las teclas y comienzan los parámetros normales.

Esta secuencia es un guión doble (-). El shell lo usa para indicar la posición en la que termina la lista de claves. Una vez que el script detecta el signo del final de las claves, lo que queda puede, sin temor a errores, procesarse como parámetros y no como claves. Consideremos un ejemplo:

#! / bin / bash while [-n "$ 1"] do case "$ 1" en -a) echo "Encontré la opción -a" ;; -b) echo "Encontré la opción -b" ;; -c) echo "Encontré la opción -c" ;; -) cambio de turno ;; *) echo "$ 1 no es una opción" ;; esac shift done count = 1 para el parámetro en [correo electrónico protegido] do echo "Parameter # $ count: $ param" count = $ (($ count + 1)) done
Este script usa el comando break para interrumpir el ciclo while si encuentra un guión doble en la línea.

Esto es lo que obtienes después de llamarlo.


Manejo de parámetros y parámetros de la línea de comandos

Como puede ver, cuando el script, al analizar los datos que se le pasan, encuentra un guión doble, termina de procesar las claves y considera como parámetros todo lo que aún no ha sido procesado.

Manejo de claves con valores

A medida que sus scripts se vuelven más complejos, se enfrentará a situaciones en las que las claves normales ya no son suficientes, lo que significa que deberá utilizar claves con determinados valores. Por ejemplo, una llamada de secuencia de comandos que utiliza esta función se ve así:

./myscript -a prueba1 -b -c prueba2
El script debe poder determinar cuándo se utilizan parámetros adicionales junto con los modificadores de la línea de comandos:

#! / bin / bash while [-n "$ 1"] do case "$ 1" en -a) echo "Encontré la opción -a" ;; -b) param = "$ 2" echo "Se encontró la opción -b, con el valor del parámetro $ param" shift ;; -c) echo "Encontré la opción -c" ;; -) cambio de turno ;; *) echo "$ 1 no es una opción" ;; esac shift done count = 1 for param in " [correo electrónico protegido]"do echo" Parámetro # $ count: $ param "count = $ (($ count + 1)) hecho
Llamemos a este script así:

./myscript -a -b test1 -d
Veamos los resultados de su trabajo.


Manejo de parámetros clave

En este ejemplo, se procesan tres claves en la construcción del caso. El modificador -b requiere un parámetro adicional. Dado que la clave que se está procesando está en la variable $ 1, su parámetro correspondiente estará en $ 2 (el comando de cambio se usa aquí, por lo tanto, a medida que avanza el procesamiento, todo lo que se pasa al script se desplaza hacia la izquierda). Cuando nos dimos cuenta de esto, solo queda extraer el valor de la variable $ 2 y tendremos el parámetro de la clave requerida. Por supuesto, aquí se necesita un comando de cambio más para que la siguiente tecla entre en $ 1.

Usando llaves estándar

Al escribir scripts de bash, puede elegir cualquier letra para las teclas de la línea de comando y establecer arbitrariamente la reacción del script a estas teclas. Sin embargo, en el mundo de Linux, algunos valores clave se han convertido en una especie de estándar que es útil cumplir. Aquí hay una lista de estas claves:
-a Muestra todos los objetos.
-c Realizar recuento.
-d Especifica el directorio.
-e Expande el objeto.
-f Especifica el archivo desde el que leer los datos.
-h Muestra la ayuda para el comando.
-i Ignorar el caso.
-l Realiza una salida de formato completo.
-n Utiliza el modo no interactivo (por lotes).
-o Le permite especificar el archivo al que desea redirigir la salida.
-q Ejecuta el script en modo silencioso.
-r Procesar carpetas y archivos de forma recursiva.
-s Ejecuta el script en modo silencioso.
-v Ejecuta una salida detallada.
-x Excluir objeto.
-y Responda sí a todas las preguntas.

Si está en Linux, probablemente esté familiarizado con muchas de estas claves. Utilizándolos en su significado generalmente aceptado en sus scripts, puede ayudar a los usuarios a interactuar con ellos sin tener que preocuparse por leer la documentación.

Recibir datos del usuario

Los interruptores y parámetros de la línea de comandos son una excelente manera de obtener datos del usuario del script, pero en algunos casos se necesita más interactividad.

A veces, los scripts necesitan datos que el usuario debe ingresar durante la ejecución del programa. El shell bash proporciona un comando de lectura para este mismo propósito.

Este comando le permite aceptar la entrada de una entrada estándar (teclado) u otros descriptores de archivo. Después de recibir los datos, este comando los coloca en una variable:

#! / bin / bash echo -n "Ingresa tu nombre:" lee el nombre echo "Hola $ nombre, bienvenido a mi programa".
Tenga en cuenta que el comando echo, que muestra el indicador, se invoca con la opción -n. Esto da como resultado que no se muestre ningún avance de línea al final del mensaje, lo que permite al usuario del script ingresar datos donde aparece el mensaje en lugar de en la siguiente línea.


Manejo de la entrada del usuario

Se pueden especificar varias variables al llamar a read:

#! / bin / bash read -p "Ingrese su nombre:" primer último eco "Sus datos para $ último, $ primero ..."
Esto es lo que generará el script después del lanzamiento.


Varias variables en el comando de lectura

Si no especifica una variable llamando a read, los datos ingresados ​​por el usuario se colocarán en la variable de entorno especial REPLY:

#! / bin / bash read -p "Ingresa tu nombre:" echo Hola $ REPLY, bienvenido a mi programa.


Usando la variable de entorno REPLY

Si el script debe continuar la ejecución independientemente de si el usuario ingresa algunos datos o no, llamando al comando de lectura, puede usar el modificador -t. A saber, el parámetro clave establece el tiempo de espera para la entrada en segundos:

#! / bin / bash if read -t 5 -p "Ingresa tu nombre:" nombre y luego echo "Hola $ nombre, bienvenido a mi script" else echo "¡Lo siento, demasiado lento!" fi
Si los datos no se ingresan en 5 segundos, el script ejecutará la rama de la declaración condicional else, generando una disculpa.


Límite de tiempo para la entrada de datos

Ingresando contraseñas

A veces es mejor no mostrar lo que el usuario ingresa en respuesta a una pregunta del guión. Por ejemplo, esto se suele hacer cuando se solicitan contraseñas. El interruptor -s al comando de lectura evita que la entrada del teclado se muestre en la pantalla. De hecho, los datos se emiten, pero el comando de lectura hace que el color del texto sea el mismo que el color de fondo.

#! / bin / bash read -s -p "Ingrese su contraseña:" pass echo "¿Es su contraseña realmente $ pass?"
Así es como funcionará este script.


Ingresando datos confidenciales

Leer datos de un archivo

El comando de lectura puede, en cada invocación, leer una línea de texto de un archivo. Cuando no haya más líneas sin leer en el archivo, simplemente se detendrá. Si necesita obtener todo el contenido de un archivo en un script, puede, usando una canalización, transferir los resultados de llamar al comando cat para el archivo, la construcción while, que contiene el comando read (por supuesto, usando el comando cat El comando parece primitivo, pero nuestro objetivo es mostrar todo de la manera más simple posible, enfocándonos en los novatos; los usuarios experimentados seguramente lo entenderán).

Escribamos un script que use el enfoque para leer archivos que se acaba de describir.

#! / bin / bash count = 1 cat miarchivo | while read line do echo "Line $ count: $ line" count = $ (($ count + 1)) done echo "Finished"
Veámoslo en acción.


Leer datos de un archivo

Aquí pasamos el contenido del archivo al ciclo while y revisamos todas las líneas de este archivo, mostrando el número y contenido de cada uno de ellos.

Resultados

Hoy hemos examinado cómo trabajar con interruptores y parámetros de línea de comando. Sin estas herramientas, el rango de uso de los scripts es extremadamente limitado. Incluso si el guión está escrito, como dicen, "para mí". Aquí examinamos los enfoques para recibir datos del usuario durante la ejecución del programa; esto hace que los scripts sean interactivos.

La próxima vez, hablemos de las operaciones de entrada y salida.

¡Queridos lectores! Gracias por compartir su experiencia en los comentarios a las partes anteriores de esta serie de materiales. Si tienes algo que decir sobre el procesamiento de todo lo que se puede pasar al script en el inicio o mientras se está ejecutando, estamos seguros de que a muchos les interesará leer al respecto.

getopts es un comando Bash incorporado que se utiliza para analizar los argumentos pasados ​​al script desde la línea de comandos. Le permite manejar una serie de opciones combinadas en un solo argumento y argumentos adicionales pasados ​​por una opción.

# script_name -abc -d / home / user

Las variables ocultas se utilizan con el comando getopts: $ OPTIND y $ OPTARG.

Un carácter de dos puntos después del nombre de una opción indica que tiene un argumento opcional.

Mientras que la opción getopts ": abcde: fg"

Por lo general, getopts se empaqueta en un bucle while, en cada paso del bucle, la siguiente opción y su argumento (si lo hay) se extraen, procesan, luego la variable oculta $ OPTIND se reduce en 1 y la transición al comienzo de un nuevo se realiza la iteración.

Las opciones que se pasan a un script desde la línea de comandos deben ir precedidas de un carácter menos (-) o más (+). Este prefijo (- o +) permite a getopts distinguir opciones de otros argumentos. De hecho, getopts no procesará argumentos a menos que estén precedidos por un - o +, y el resaltado de opciones se detendrá tan pronto como se encuentre el primer argumento.

La construcción típica de bucle while con getopts es ligeramente diferente de la estándar debido a la ausencia de corchetes que prueban la condición de la continuación del bucle.
Puede ver cómo funciona getopts con el siguiente script.

prueba-getopts

uso () (
echo "El script` basename $ 0` está destinado a demostrar las capacidades de getopts."
eco ""
echo "Uso:` nombre base $ 0` -abef -c C -d D "
echo -e "\ 033 # ¿Se invocó el script sin argumentos?
luego
uso # Si se inicia sin argumentos, muestra la ayuda
salir de $ E_OPTERROR # y salir con un código de error
fi

while getopts Opción "abc: d: ef"
hacer
caso $ Opción en
a | b) echo “Acción 1: Opción - $ Opción. Número de opción: $ OPTIND. Argumento: $ OPTARG ";;
c) echo “Acción 2: Opción - $ Opción. Número de opción: $ OPTIND. Argumento: $ OPTARG ";;
d) echo “Acción 3: Opción - $ Opción. Número de opción: $ OPTIND. Argumento: $ OPTARG ";;
e) echo “Acción 4: Opción - $ Opción. Número de opción: $ OPTIND. Argumento: $ OPTARG ";;
f) echo “Acción 5: Opción - $ Opción. Número de opción: $ OPTIND. Argumento: $ OPTARG ";;
*) echo "Clave seleccionada no válida".
uso
salir $ E_OPTERROR ;; # DEFECTO
esac
hecho
turno $ (($ OPTIND - 1))

Intente ejecutarlo así:

Prueba-getopts -abc con-opt
prueba-getopts -abefd d-opt

Y ahora así:

Prueba-getopts -abcdef
prueba-getopts -cd d-opt

Este comportamiento de getopts está relacionado con el hecho de que la opción -c espera un argumento adicional.