GNU/Linux >> Tutoriales Linux >  >> Linux

Script Bash (II)

Este es el segundo artículo de una serie centrada en el scripting de Gnu Bash. En el primer artículo sobre secuencias de comandos de bash, acabamos de crear la secuencia de comandos más simple:comandos simples, uno tras otro. También vimos el uso de algunas variables. Este artículo cubrirá las estructuras de control bash.

Estructuras de control

Como he dicho en el artículo anterior, la pereza es la clave del éxito. Si tengo que ejecutar algunos comandos, un tiempo después los mismos comandos en el mismo orden, cuando llegue la tercera vez, abriré un editor de texto y pegaré esos comandos para guardarlos como un script.

Después de un par de días, ese guión comenzó a crecer, tanto en extensión como en complejidad. Necesito formas de controlar el flujo de ejecución, por ejemplo:

  • si algo sucede, haz algo, o si algo no sucede, haz otra cosa;
  • mientras algo está sucediendo, hacer algo una y otra vez, o hacer algo una y otra vez;
  • o dependiendo del valor de una variable o de lo que suceda, hacer esto o aquello u otro,
  • etc

Esto es para lo que están destinadas las estructuras de control de bash (en realidad, en bash o en cualquier otro lenguaje de programación). Pero primero, necesitamos saber acerca de:

Estado de salida

Desde la página de manual de bash:

«El estado de salida de un comando ejecutado es el valor devuelto por la llamada al sistema waitpid o una función equivalente. Los estados de salida se encuentran entre 0 y 255. (…) Un estado de salida de cero indica éxito (o, igual a 'verdadero'). Un estado de salida distinto de cero indica un error (o, igual a 'falso'). (…. Por ejemplo:) Si no se encuentra un comando, el proceso secundario creado para ejecutarlo devuelve un estado de 127. Si se encuentra un comando pero no es ejecutable, el estado de retorno es 126 ».

tl;dr:los estados de salida de 0 significan verdadero , éxito; cualquier otro valor significa falso . Es importante aprender esto porque tomar decisiones de verdadero/falso es verificar el estado de salida de un comando.

Bash almacena el estado de salida del último comando ejecutado en $? variables.

si-entonces-otro

Este es el si pasa algo (algo sucede significa un comando con un estado de salida de cero) hacer algo , o bien hacer otra cosa. La sintaxis es:

if command
then
	command1
	command2
	...
else
	commandA
	commandB
	...
fi

Como puede ver en la captura de pantalla, se puede escribir en una sola línea, separando cada comando con un punto y coma:

if command; then command1; command2;...; else commandA; commandB;...;fi

Dependiendo de la complejidad del bloque si-entonces, podría ser más fácil de leer o más difícil de leer con el estilo 'oneliner'.

¿Qué sucede si desea ejecutar algún comando si algo sucede? Ejecute otro comando solo si algo más sucede? use la palabra clave elif (si no):

if command
then
	command1
	command2
	...
elif other_command
	commandA
	commandB
	...
else
	another block of commands
fi

Un bloque if-then-else termina con la palabra clave fi (si está al revés).

Comparación de cadenas y números

¿Recuerdas las variables? con frecuencia el algo sucede es que dependiendo del valor de una variable queramos ejecutar unos comandos u otros.
Para comparar si una cadena es igual a alguna palabra o si un número es menor que otro usamos el comando test . La sintaxis general es:

test expression

Si expresión se omite se considera falso (estado de salida> 0). Si expresión es solo una cadena de texto, es verdad. Esto podría ser complicado, por ejemplo:

$ test false; echo $?
0

No estamos probando el estado de salida del comando falso (hay un comando falso ) pero la cadena false contra nada. La otra forma de ejecutar el comando de prueba es encerrar la expresión entre corchetes. Esta otra forma es más fácil de leer dentro de un bloque if-then-else.

Hay más expresiones, esas son las que considero más importantes. Lea la página de manual de prueba para aprender las otras expresiones.

Fíjese que hay un espacio entre ambos corchetes y la expresión. Ahora podemos usar test para hacer algo en función del valor de una variable. Por ejemplo:

caso

Cuando queremos probar una variable contra varios valores, podemos agregar múltiples elif a nuestro bloque if-then-else como este:

if [ $a = "value1" ]
then
	command1 for value1
	...
	commandN for value1
elif [ $a = "value2" ] 
then
	command1 for value2
	...
	commandN for value2
...
elif [ $a = "valueN" ] 
then
	command1 for valueN
	...
	commandN for valueN
else
	command1 for every other value
	...
	commandN for every other value
fi

O podemos reemplazarlo con un comando de mayúsculas y minúsculas que es más fácil de leer y escribir:

case expression in
	value1)
		command1 for value1
		...
		commandN for value1
		;;
	value2)
		command1 for value2
		...
		commandN for value2
		;;
	...
	*)
		command1 for every other value
		...
		commandN for every other value
		;;
esac

Además, menos pulsaciones de teclas, no olvides ser lo suficientemente perezoso para que la computadora funcione para ti. El último valor * es el caso predeterminado, cualquier otro valor que no haya coincidido antes. Caso al revés, esac , es análoga a la declaración fi. Si ;; se utiliza el operador, no se intentan coincidencias posteriores después de la primera coincidencia de patrón. Para probar el siguiente patrón, use ;;* operador. Por ejemplo:

mientras y hasta

Mientras que es hacer algo una y otra vez mientras sucede algo. Y hasta es lo mismo pero negado (hacer algo una y otra vez mientras algo no sucede). La sintaxis general es:

while command
do
	command1
	command2
	...
	commandN
done

Para hacer algo mientras no está sucediendo (es decir, el estado existente es diferente de 0), reemplace mientras con hasta. Vea algunos ejemplos:

Observe que no produjeron el mismo resultado. En el bloque while, cuando $a alcanza el valor 4, no es más bajo que 4, por lo que la prueba se evalúa como falsa (y el código de salida es> 0). En el bloque hasta, cuando $a alcanza el valor 4, no es mayor que 4.

Un reloj en tu terminal

A veces estoy probando un cronjob y eso me pone ansioso hasta que se ejecuta. Utilizo el comando verdadero (que, como puede imaginar, produce un estado de salida 0) como condición y ejecuto la fecha del comando una y otra vez:

while true
do
	date
	sleep 1
	clear
done

Esto correría más rápido, pero puedo interrumpir con ctrl-c.

for-in -hacer

Este tipo de bucle itera sobre una lista proporcionada asignando cada elemento a una variable. Sintaxis:

for i in list of words
do
	command1
	...
	commandN
done

Esto es más fácil de ver en un ejemplo:

Estén atentos

Las cosas se están poniendo complejas, pero queremos que nuestros guiones tomen algunas decisiones para hacer esto o aquello. Iba a cubrir otros temas, pero este artículo sobre las estructuras de control bash ha crecido demasiado.

En los próximos, cubriré las tuberías y la redirección. Probablemente volveré a estas estructuras de control de bash con los ejemplos, algo así como usar la salida de un comando en un bucle for-in y cosas así.


Linux
  1. Explicación del comando Bash trap

  2. Bash secuencias de comandos (I)

  3. ¿El comando "eval" en Bash?

  4. comando de exportación bash

  5. Ejecute el comando bash en la canalización de jenkins

Bash Scripting – Manipulación de cadenas

Bash Scripting - Comando Printf explicado con ejemplos

Bash Scripting – Declaración de caso

Cómo usar el comando de fecha en Bash Scripting en Linux

Script Bash (III)

Bash Beginner Series #2:Comprender las variables en Bash Shell Scripting

    operandos verdadero si
    expresión verdadero
    ! expresión false (expresión negada)
    expresiónA -a expresiónB Y. ambas expresiones son verdaderas
    expresiónA -o expresiónB O. una de las expresiones es verdadera
    cadena1 =cadena2 ambas cadenas son iguales
    cadena1 !=cadena2 las cadenas son diferentes
    int1 -eq int2 entero1 es igual a entero2
    int1-ge int2 int1>=int2
    int1 -gt int2 int1> int2
    int1 -le int2 int1 <=int2
    int1 -lt int2 int1
    int1 -ne int2 int1 no es igual a int2
    -archivo e el archivo existe
    -d directorio el archivo existe y es un directorio