Ventanas.  virus  Cuadernos.  Internet.  oficina.  Utilidades.  Conductores

El shell bash admite para bucles, que le permiten organizar la iteración de secuencias de valores. eso es lo que estructura basica tales ciclos:

Para var en la lista, haz comandos hechos
En cada iteración del bucle, el siguiente valor de la lista se escribirá en la variable var. En el primer paso del ciclo, por lo tanto, se utilizará el primer valor de la lista. En el segundo, el segundo, y así sucesivamente, hasta que el bucle llega al último elemento.

Iterando sobre valores simples

Quizás el ejemplo más simple de un bucle for en scripts bash es iterar sobre una lista de valores simples:

#!/bin/bash para var en primero segundo tercero cuarto quinto hacer eco El elemento $var hecho
El resultado de este script se muestra a continuación. Se ve claramente que los elementos de la lista entran secuencialmente en la variable $var. Esto sucede hasta que el ciclo llega al último de ellos.


Un bucle for simple

Tenga en cuenta que la variable $var conserva su valor al salir del ciclo, su contenido se puede cambiar, en general, puede trabajar con ella como con cualquier otra variable.

Iterando sobre valores complejos

La lista utilizada para inicializar el bucle for puede contener no solo cadenas simples que constan de una palabra, sino también frases completas que incluyen varias palabras y signos de puntuación. Por ejemplo, todo podría verse así:

#!/bin/bash para var en el primero "el segundo" " El tercero" "Lo haré" do echo "Esto es: $var" hecho
Esto es lo que sucede después de que este bucle recorre la lista. Como podéis ver, el resultado es bastante esperado.


Iterando sobre valores complejos
TNW-CUS-FMP - código de promoción para un 10 % de descuento en nuestros servicios, disponible para activación dentro de 7 días"

Inicializando el bucle con una lista obtenida de los resultados del comando

Otra forma de inicializar un bucle for es pasarle una lista que es el resultado de algún comando. Utiliza la sustitución de comandos para ejecutarlos y obtener los resultados de su trabajo.

#!/bin/bash file="myfile" for var in $(cat $file) do echo "$var" done
Este ejemplo usa el comando cat para leer el contenido de un archivo. La lista de valores resultante se pasa al bucle y se muestra en la pantalla. Tenga en cuenta que el archivo al que accedemos contiene una lista de palabras separadas por saltos de línea, no se utilizan espacios.


Bucle que itera sobre el contenido de un archivo

Cabe señalar aquí que tal enfoque, si se espera un procesamiento de datos línea por línea, no funcionará para un archivo de una estructura más compleja, cuyas líneas pueden contener varias palabras separadas por espacios. El bucle procesará palabras sueltas, no líneas.

¿Qué pasa si no es lo que quieres en absoluto?

Separadores de campo

La razón de la característica anterior es la especial Variable ambiental, que se llama IFS (Internal Field Separator) y le permite especificar separadores de campo. Por defecto concha bash trata los siguientes caracteres como separadores de campo:
  • Espacio
  • Signo de pestaña
  • Carácter de avance de línea
Si bash encuentra alguno de estos caracteres en los datos, asume que está precedido por el siguiente valor independiente en la lista.

Para resolver el problema, puede cambiar temporalmente la variable de entorno IFS. Aquí se explica cómo hacerlo en un script bash, asumiendo que solo necesita una nueva línea como separador de campo:

IFS=$"\n"
Después de agregar este comando a un script bash, funcionará como debería, ignorando espacios y tabulaciones, considerando solo líneas nuevas como separadores de campo.

#!/bin/bash file="/etc/passwd" IFS=$"\n" for var in $(cat $file) do echo " $var" done
Si se ejecuta este script, generará exactamente lo que se requiere de él, dando, en cada iteración del bucle, acceso a la siguiente línea escrita en el archivo.


Recorrido línea por línea del contenido de un archivo en un bucle for

Otros caracteres pueden ser delimitadores. Por ejemplo, arriba mostramos el contenido del archivo /etc/passwd. Los datos de usuario en las filas están separados por dos puntos. Si necesita procesar dichas filas en un bucle, IFS se puede configurar así:

Atravesar archivos contenidos en un directorio

Uno de los usos más comunes de bucles for en scripts bash es recorrer archivos en un directorio y procesar esos archivos.

Por ejemplo, así es como enumerar archivos y carpetas:

#!/bin/bash for file in /home/likegeeks/* do if [ -d "$file" ] luego echo "$file is a directory" elif [ -f "$file" ] then echo "$file is a archivo" hecho
Si ha tratado el material anterior en esta serie de artículos, debe comprender cómo funciona la construcción si-entonces, así como también cómo distinguir un archivo de una carpeta. Si le resulta difícil comprender el código anterior, vuelva a leer este material.

Esto es lo que generará el script.


Listado del contenido de una carpeta

Preste atención a cómo inicializamos el ciclo, es decir, al comodín "*" al final de la dirección de la carpeta. Este carácter se puede considerar como un comodín que significa "todos los archivos con cualquier nombre". le permite organizar la sustitución automática de nombres de archivo que coincidan con el patrón.

Al verificar la condición en una declaración if, encerramos el nombre de la variable entre comillas. Esto se hace porque el nombre del archivo o carpeta puede contener espacios.

Estilo C para bucles

Si está familiarizado con el lenguaje de programación C, la sintaxis para describir bash for loops puede parecerle extraña, ya que obviamente está acostumbrado a esta descripción de loops:

Para (i = 0; yo< 10; i++) { printf("number is %d\n", i); }
Los scripts de Bash pueden usar bucles for, que se parecen mucho a los bucles de estilo C, pero con algunas diferencias. El diagrama de ciclo con un enfoque similar se ve así:

For ((valor variable inicial; condición de terminación del ciclo; cambio de variable))
En bash, esto se puede escribir así:

Para ((a = 1; a< 10; a++))
Y aquí hay un ejemplo de trabajo:

#!/bin/bash para ((i=1; i<= 10; i++)) do echo "number is $i" done
Este código imprimirá una lista de números del 1 al 10.

Operación de bucle estilo C

mientras bucle

La construcción for no es la única forma de organizar bucles en scripts bash. También puede usar bucles while aquí. En un bucle de este tipo, puede especificar un comando para verificar una determinada condición y ejecutar el cuerpo del bucle hasta que la condición verificada devuelva cero, o una señal de la finalización exitosa de alguna operación. Cuando la condición del bucle devuelve un valor distinto de cero, lo que significa un error, el bucle se detendrá.

Aquí hay un diagrama de cómo se organizan los bucles while
comando de prueba de condición while
hacer
otros equipos
hecho

Veamos un script de ejemplo con un bucle como este:

#!/bin/bash var1=5 while [ $var1 -gt 0 ] echo $var1 var1=$[ $var1 - 1 ] hecho
A la entrada del bucle, se comprueba la variable $var1 para ver si es mayor que cero. Si es así, se ejecuta el cuerpo del bucle restando uno al valor de la variable. Esto sucede en cada iteración, mientras imprimimos el valor de la variable en la consola antes de que se modifique. Tan pronto como $var1 se convierte en 0, el ciclo se detiene.

El resultado del ciclo while

Si no modifica la variable $var1, el script entrará en un bucle infinito.

Bucles anidados

Puede usar cualquier comando en el cuerpo del bucle, incluido el lanzamiento de otros bucles. Tales construcciones se denominan bucles anidados:

#!/bin/bash para ((a = 1; a<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
A continuación se muestra lo que generará este script. Como puede ver, primero se ejecuta la primera iteración del bucle externo, luego tres iteraciones del interno, después de su finalización, el bucle externo vuelve a entrar en juego, luego nuevamente el interno.

Bucles anidados

Procesando el contenido del archivo

La mayoría de las veces, los bucles anidados se utilizan para procesar archivos. Entonces, el ciclo externo está iterando a través de las líneas del archivo, y el ciclo interno ya está trabajando con cada línea. Por ejemplo, así es como se ve el archivo /etc/passwd:

#!/bin/bash IFS=$"\n" para la entrada en $(cat /etc/passwd) haga eco "Valores en $entrada –" IFS=: para el valor en $entrada haga eco "$valor" hecho hecho
Este script tiene dos bucles. El primero itera sobre las líneas, usando el carácter de nueva línea como separador. El interno está ocupado analizando cadenas cuyos campos están separados por dos puntos.

Procesamiento de datos de archivos

Este enfoque se puede utilizar cuando se procesan archivos en formato CSV o cualquier archivo similar, escribiendo, según sea necesario, un carácter delimitador en la variable de entorno IFS.

Gestión del ciclo

Quizás, después de ingresar al ciclo, será necesario detenerlo cuando la variable del ciclo alcance un cierto valor que no corresponda a la condición de finalización del ciclo establecida inicialmente. ¿Será necesario esperar a la finalización normal del ciclo en tal situación? Por supuesto que no, y en tales casos los siguientes dos comandos serán útiles:
  • romper
  • continuar

comando romper

Este comando le permite interrumpir la ejecución del bucle. Se puede utilizar tanto para bucles for como para bucles while:

#!/bin/bash para var1 en 1 2 3 4 5 6 7 8 9 10 hacer si [ $var1 -eq 5 ] luego romper fi echo "Número: $var1" hecho
Dicho ciclo, en condiciones normales, recorrerá toda la lista de valores de la lista. Sin embargo, en nuestro caso, su ejecución se interrumpirá cuando la variable $var1 sea igual a 5.

Salida anticipada del bucle for

Aquí está lo mismo, pero para el ciclo while:

#!/bin/bash var1=1 while [ $var1 -lt 10 ] hacer si [ $var1 -eq 5 ] luego romper fi echo "Iteración: $var1" var1=$(($var1 + 1)) hecho
El comando break, ejecutado cuando el valor de $var1 se convierte en 5, rompe el ciclo. La misma salida que en el ejemplo anterior se enviará a la consola.

continuar comando

Cuando este comando se encuentra en el cuerpo del bucle, la iteración actual finaliza antes de lo previsto y comienza la siguiente, sin salir del bucle. Veamos el comando continuar en el bucle for:

#!/bin/bash para ((var1 = 1; var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
Cuando la condición dentro del bucle es verdadera, es decir, cuando $var1 es mayor que 5 y menor que 10, el shell ejecuta el comando continuar. Esto conduce a la omisión de los comandos que quedan en el cuerpo del ciclo y la transición a la siguiente iteración.

comando continuar en un bucle for

Manejo de la salida que se ejecuta en un bucle

La salida de datos en un bucle se puede procesar redirigiendo la salida o pasándola a la canalización. Esto se hace agregando comandos de procesamiento de salida después de la instrucción done.

Por ejemplo, en lugar de mostrar en la pantalla lo que se genera en el bucle, puede escribirlo todo en un archivo o pasarlo a otro lugar:

#!/bin/bash para ((a = 1; a< 10; a++)) do echo "Number is $a" done >myfile.txt echo "terminado".
El shell creará el archivo myfile.txt y redirigirá la salida de la construcción for a este archivo. Abramos el archivo y asegurémonos de que contiene exactamente lo que esperamos.

Redirigir la salida del bucle a un archivo

Ejemplo: encontrar ejecutables

Usemos lo que ya hemos cubierto y escribamos algo útil. Por ejemplo, si necesita averiguar exactamente qué archivos ejecutables están disponibles en el sistema, puede escanear todas las carpetas escritas en la variable de entorno PATH. Ya tenemos todo el arsenal de herramientas que necesitamos para esto, solo necesitamos ponerlo todo junto:

#!/bin/bash IFS=: para la carpeta en $PATH haga eco "$carpeta:" para el archivo en $carpeta/* haga si [ -x $archivo] luego haga eco "$archivo" hecho hecho
Tal secuencia de comandos, pequeña y sin complicaciones, hizo posible obtener una lista de archivos ejecutables almacenados en carpetas de PATH.

Buscar archivos ejecutables en carpetas desde la variable PATH

Resultados

Hoy hablamos sobre los bucles for y while en los scripts bash, cómo ejecutarlos, cómo administrarlos. Ahora sabe cómo procesar cadenas con diferentes separadores en bucles, sabe cómo redirigir la salida de datos en bucles a archivos, cómo ver y analizar el contenido de los directorios.

Asumiendo que eres un desarrollador de bash scripts que solo sabe sobre ellos lo que se dice en la primera parte de esta serie de artículos, y en esta, la segunda, entonces ya puedes escribir algo útil. Más adelante está la tercera parte, después de haberla tratado, aprenderá cómo pasar parámetros y cambios de línea de comando a scripts de bash, y qué hacer con todo eso.

El shell bash admite bucles, lo que le permite iterar sobre secuencias de valores. Aquí está la estructura básica de tales bucles:

Para var en la lista, haz comandos hechos
En cada iteración del bucle, el siguiente valor de la lista se escribirá en la variable var. En el primer paso del ciclo, por lo tanto, se utilizará el primer valor de la lista. En el segundo, el segundo, y así sucesivamente, hasta que el bucle llega al último elemento.

Iterando sobre valores simples

Quizás el ejemplo más simple de un bucle for en scripts bash es iterar sobre una lista de valores simples:

#!/bin/bash para var en primero segundo tercero cuarto quinto hacer eco El elemento $var hecho
El resultado de este script se muestra a continuación. Se ve claramente que los elementos de la lista entran secuencialmente en la variable $var. Esto sucede hasta que el ciclo llega al último de ellos.


Un bucle for simple

Tenga en cuenta que la variable $var conserva su valor al salir del ciclo, su contenido se puede cambiar, en general, puede trabajar con ella como con cualquier otra variable.

Iterando sobre valores complejos

La lista utilizada para inicializar el bucle for puede contener no solo cadenas simples que constan de una palabra, sino también frases completas que incluyen varias palabras y signos de puntuación. Por ejemplo, todo podría verse así:

#!/bin/bash for var in first "el segundo" "el tercero" "Lo haré" do echo "Esto es: $var" hecho
Esto es lo que sucede después de que este bucle recorre la lista. Como podéis ver, el resultado es bastante esperado.


Iterando sobre valores complejos
TNW-CUS-FMP - código de promoción para un 10 % de descuento en nuestros servicios, disponible para activación dentro de 7 días"

Inicializando el bucle con una lista obtenida de los resultados del comando

Otra forma de inicializar un bucle for es pasarle una lista que es el resultado de algún comando. Utiliza la sustitución de comandos para ejecutarlos y obtener los resultados de su trabajo.

#!/bin/bash file="myfile" for var in $(cat $file) do echo "$var" done
Este ejemplo usa el comando cat para leer el contenido de un archivo. La lista de valores resultante se pasa al bucle y se muestra en la pantalla. Tenga en cuenta que el archivo al que accedemos contiene una lista de palabras separadas por saltos de línea, no se utilizan espacios.


Bucle que itera sobre el contenido de un archivo

Cabe señalar aquí que tal enfoque, si se espera un procesamiento de datos línea por línea, no funcionará para un archivo de una estructura más compleja, cuyas líneas pueden contener varias palabras separadas por espacios. El bucle procesará palabras sueltas, no líneas.

¿Qué pasa si no es lo que quieres en absoluto?

Separadores de campo

El motivo de la característica anterior es una variable de entorno especial llamada IFS (separador de campo interno) que le permite especificar separadores de campo. De forma predeterminada, el shell bash trata los siguientes caracteres como separadores de campo:
  • Espacio
  • Signo de pestaña
  • Carácter de avance de línea
Si bash encuentra alguno de estos caracteres en los datos, asume que está precedido por el siguiente valor independiente en la lista.

Para resolver el problema, puede cambiar temporalmente la variable de entorno IFS. Aquí se explica cómo hacerlo en un script bash, asumiendo que solo necesita una nueva línea como separador de campo:

IFS=$"\n"
Después de agregar este comando a un script bash, funcionará como debería, ignorando espacios y tabulaciones, considerando solo líneas nuevas como separadores de campo.

#!/bin/bash file="/etc/passwd" IFS=$"\n" for var in $(cat $file) do echo " $var" done
Si se ejecuta este script, generará exactamente lo que se requiere de él, dando, en cada iteración del bucle, acceso a la siguiente línea escrita en el archivo.


Recorrido línea por línea del contenido de un archivo en un bucle for

Otros caracteres pueden ser delimitadores. Por ejemplo, arriba mostramos el contenido del archivo /etc/passwd. Los datos de usuario en las filas están separados por dos puntos. Si necesita procesar dichas filas en un bucle, IFS se puede configurar así:

Atravesar archivos contenidos en un directorio

Uno de los usos más comunes de bucles for en scripts bash es recorrer archivos en un directorio y procesar esos archivos.

Por ejemplo, así es como enumerar archivos y carpetas:

#!/bin/bash for file in /home/likegeeks/* do if [ -d "$file" ] luego echo "$file is a directory" elif [ -f "$file" ] then echo "$file is a archivo" hecho
Si ha tratado con esta serie de artículos, debe comprender la estructura de la construcción si-entonces, así como también cómo distinguir un archivo de una carpeta. Si le resulta difícil comprender el código anterior, vuelva a leer este material.

Esto es lo que generará el script.


Listado del contenido de una carpeta

Preste atención a cómo inicializamos el ciclo, es decir, al comodín "*" al final de la dirección de la carpeta. Este carácter se puede considerar como un comodín que significa "todos los archivos con cualquier nombre". le permite organizar la sustitución automática de nombres de archivo que coincidan con el patrón.

Al verificar la condición en una declaración if, encerramos el nombre de la variable entre comillas. Esto se hace porque el nombre del archivo o carpeta puede contener espacios.

Estilo C para bucles

Si está familiarizado con el lenguaje de programación C, la sintaxis para describir bash for loops puede parecerle extraña, ya que obviamente está acostumbrado a esta descripción de loops:

Para (i = 0; yo< 10; i++) { printf("number is %d\n", i); }
Los scripts de Bash pueden usar bucles for, que se parecen mucho a los bucles de estilo C, pero con algunas diferencias. El diagrama de ciclo con un enfoque similar se ve así:

For ((valor variable inicial; condición de terminación del ciclo; cambio de variable))
En bash, esto se puede escribir así:

Para ((a = 1; a< 10; a++))
Y aquí hay un ejemplo de trabajo:

#!/bin/bash para ((i=1; i<= 10; i++)) do echo "number is $i" done
Este código imprimirá una lista de números del 1 al 10.

Operación de bucle estilo C

mientras bucle

La construcción for no es la única forma de organizar bucles en scripts bash. También puede usar bucles while aquí. En un bucle de este tipo, puede especificar un comando para verificar una determinada condición y ejecutar el cuerpo del bucle hasta que la condición verificada devuelva cero, o una señal de la finalización exitosa de alguna operación. Cuando la condición del bucle devuelve un valor distinto de cero, lo que significa un error, el bucle se detendrá.

Aquí hay un diagrama de cómo se organizan los bucles while
comando de prueba de condición while
hacer
otros equipos
hecho

Veamos un script de ejemplo con un bucle como este:

#!/bin/bash var1=5 while [ $var1 -gt 0 ] echo $var1 var1=$[ $var1 - 1 ] hecho
A la entrada del bucle, se comprueba la variable $var1 para ver si es mayor que cero. Si es así, se ejecuta el cuerpo del bucle restando uno al valor de la variable. Esto sucede en cada iteración, mientras imprimimos el valor de la variable en la consola antes de que se modifique. Tan pronto como $var1 se convierte en 0, el ciclo se detiene.

El resultado del ciclo while

Si no modifica la variable $var1, el script entrará en un bucle infinito.

Bucles anidados

Puede usar cualquier comando en el cuerpo del bucle, incluido el lanzamiento de otros bucles. Tales construcciones se denominan bucles anidados:

#!/bin/bash para ((a = 1; a<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
A continuación se muestra lo que generará este script. Como puede ver, primero se ejecuta la primera iteración del bucle externo, luego tres iteraciones del interno, después de su finalización, el bucle externo vuelve a entrar en juego, luego nuevamente el interno.

Bucles anidados

Procesando el contenido del archivo

La mayoría de las veces, los bucles anidados se utilizan para procesar archivos. Entonces, el ciclo externo está iterando a través de las líneas del archivo, y el ciclo interno ya está trabajando con cada línea. Por ejemplo, así es como se ve el archivo /etc/passwd:

#!/bin/bash IFS=$"\n" para la entrada en $(cat /etc/passwd) haga eco "Valores en $entrada –" IFS=: para el valor en $entrada haga eco "$valor" hecho hecho
Este script tiene dos bucles. El primero itera sobre las líneas, usando el carácter de nueva línea como separador. El interno está ocupado analizando cadenas cuyos campos están separados por dos puntos.

Procesamiento de datos de archivos

Este enfoque se puede utilizar cuando se procesan archivos en formato CSV o cualquier archivo similar, escribiendo, según sea necesario, un carácter delimitador en la variable de entorno IFS.

Gestión del ciclo

Quizás, después de ingresar al ciclo, será necesario detenerlo cuando la variable del ciclo alcance un cierto valor que no corresponda a la condición de finalización del ciclo establecida inicialmente. ¿Será necesario esperar a la finalización normal del ciclo en tal situación? Por supuesto que no, y en tales casos los siguientes dos comandos serán útiles:
  • romper
  • continuar

comando romper

Este comando le permite interrumpir la ejecución del bucle. Se puede utilizar tanto para bucles for como para bucles while:

#!/bin/bash para var1 en 1 2 3 4 5 6 7 8 9 10 hacer si [ $var1 -eq 5 ] luego romper fi echo "Número: $var1" hecho
Dicho ciclo, en condiciones normales, recorrerá toda la lista de valores de la lista. Sin embargo, en nuestro caso, su ejecución se interrumpirá cuando la variable $var1 sea igual a 5.

Salida anticipada del bucle for

Aquí está lo mismo, pero para el ciclo while:

#!/bin/bash var1=1 while [ $var1 -lt 10 ] hacer si [ $var1 -eq 5 ] luego romper fi echo "Iteración: $var1" var1=$(($var1 + 1)) hecho
El comando break, ejecutado cuando el valor de $var1 se convierte en 5, rompe el ciclo. La misma salida que en el ejemplo anterior se enviará a la consola.

continuar comando

Cuando este comando se encuentra en el cuerpo del bucle, la iteración actual finaliza antes de lo previsto y comienza la siguiente, sin salir del bucle. Veamos el comando continuar en el bucle for:

#!/bin/bash para ((var1 = 1; var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
Cuando la condición dentro del bucle es verdadera, es decir, cuando $var1 es mayor que 5 y menor que 10, el shell ejecuta el comando continuar. Esto conduce a la omisión de los comandos que quedan en el cuerpo del ciclo y la transición a la siguiente iteración.

comando continuar en un bucle for

Manejo de la salida que se ejecuta en un bucle

La salida de datos en un bucle se puede procesar redirigiendo la salida o pasándola a la canalización. Esto se hace agregando comandos de procesamiento de salida después de la instrucción done.

Por ejemplo, en lugar de mostrar en la pantalla lo que se genera en el bucle, puede escribirlo todo en un archivo o pasarlo a otro lugar:

#!/bin/bash para ((a = 1; a< 10; a++)) do echo "Number is $a" done >myfile.txt echo "terminado".
El shell creará el archivo myfile.txt y redirigirá la salida de la construcción for a este archivo. Abramos el archivo y asegurémonos de que contiene exactamente lo que esperamos.

Redirigir la salida del bucle a un archivo

Ejemplo: encontrar ejecutables

Usemos lo que ya hemos cubierto y escribamos algo útil. Por ejemplo, si necesita averiguar exactamente qué archivos ejecutables están disponibles en el sistema, puede escanear todas las carpetas escritas en la variable de entorno PATH. Ya tenemos todo el arsenal de herramientas que necesitamos para esto, solo necesitamos ponerlo todo junto:

#!/bin/bash IFS=: para la carpeta en $PATH haga eco "$carpeta:" para el archivo en $carpeta/* haga si [ -x $archivo] luego haga eco "$archivo" hecho hecho
Tal secuencia de comandos, pequeña y sin complicaciones, hizo posible obtener una lista de archivos ejecutables almacenados en carpetas de PATH.

Buscar archivos ejecutables en carpetas desde la variable PATH

Resultados

Hoy hablamos sobre los bucles for y while en los scripts bash, cómo ejecutarlos, cómo administrarlos. Ahora sabe cómo procesar cadenas con diferentes separadores en bucles, sabe cómo redirigir la salida de datos en bucles a archivos, cómo ver y analizar el contenido de los directorios.

Asumiendo que eres un desarrollador de bash scripts que solo sabe sobre ellos lo que se dice en esta serie de artículos, y en este, el segundo, entonces ya puedes escribir algo útil. Más adelante está la tercera parte, después de haberla tratado, aprenderá cómo pasar parámetros y cambios de línea de comando a scripts de bash, y qué hacer con todo eso.

Breve descripción de la diferencia en los tipos de bucle:

for - realizará una acción siempre que haya objetos para realizar (por ejemplo, leer un flujo desde stdin , un archivo o una función);
while - realiza una acción hasta que condición es verdad;
hasta - se ejecutará hasta condición no se hará realidad, i.e. mientras sea falso.

En bucle

Considere esta versión del script con un bucle:

$ cat loop.sh #!/bin/bash for variable in `ls -1` do echo "$variable" hecho

La sintaxis es muy simple y se muestra claramente en el ejemplo:

for (iniciar el ciclo) variable (declarar una variable para realizar acciones) in (dirigir el flujo al ciclo) `ls -1` (comando a ejecutar y pasar a la variable $variable). do y done son el "cuerpo" del ciclo, dentro del cual se realizarán las acciones principales sobre los datos recibidos, y echo "$variable" es la acción en sí realizada por el ciclo.

Ahora cambiemos un poco el ejemplo, y en lugar de especificar explícitamente el comando, aplicaremos la segunda variable:

$ cat loop.sh #!/bin/bash ls=`ls -1` for variable in $ls do echo "$variable" hecho

Ahora el comando ls -1 se pasa en una variable separada, lo que permite un trabajo más flexible con el ciclo. En lugar de una variable en un bucle, también puede usar una función:

$ cat loop.sh #!/bin/bash lsl () ( ls -1 ) for variable in `lsl` do echo "$variable" hecho

La condición principal del bucle for es que se ejecutará siempre que el comando que se le pase tenga objetos para la acción. Según el ejemplo anterior, siempre que haya archivos para mostrar en la lista ls -1, el bucle los pasará a una variable y ejecutará el "cuerpo del bucle". Tan pronto como finalice la lista de archivos en el directorio, el bucle completará su ejecución.

Vamos a complicar un poco el ejemplo.

El directorio contiene una lista de archivos:

$ ls -1 archivo1 archivo2 archivo3 archivo4 archivo5 loop.sh nofile1 nofile2 nofile3 nofile4 nofile5

Necesitamos elegir entre ellos solo aquellos que no tienen la palabra " No«:

$ cat loop.sh #!/bin/bash lsl=`ls -1` for variable en $lsl do echo "$variable" | grep -v "no" hecho $ ./loop.sh archivo1 archivo2 archivo3 archivo4 archivo5 loop.sh

En un bucle, también puede usar expresiones condicionales ( expresiones condicionales) […] para probar las condiciones y la sentencia break para romper el bucle si se activa la condición.

Considere este ejemplo:

$ cat loop.sh #!/bin/bash lsl=`ls -1` para variable en $lsl do if [ $variable != "loop.sh" ] luego echo "$variable" | grep -v "no" más romper fi hecho

El bucle se ejecutará hasta que se encuentre el archivo loop.sh. Tan pronto como la ejecución del bucle llegue a este archivo, el bucle será interrumpido por el comando break:

$ ./loop.sh archivo1 archivo2 archivo3 archivo4 archivo5

Otro ejemplo es el uso de operaciones aritméticas justo antes de la ejecución del cuerpo del ciclo:

$ cat loop.sh #!/bin/bash for ((cuenta=1; cuenta<11; count++)) do echo "$count" done

Aquí establecemos tres comandos de control: contar = 1, una condición de control, mientras que el recuento es inferior a 11, y un comando para ejecutar: contar +1:

Bucles WHILE y UNTIL

Un ejemplo simple que demuestra cómo funciona bien el bucle while:

$ cat loop.sh #!/bin/bash count=0 while [ $count -lt 10 ] do ((count++)) echo $count done

Establecemos la variable $count en cero, después de lo cual ejecutamos el bucle while con la condición "while $count is less than ten, loop". En el cuerpo del bucle ejecutamos incremento de sufijo+1 a la variable $count e imprime el resultado en stdout.

Resultado de la ejecución:

$ ./bucle.sh 1 2 3 4 5 6 7 8 9 10

Tan pronto como el valor de la variable $count se convirtió en 10, el bucle se detuvo.

Un buen ejemplo de un bucle "infinito" que demuestra cómo funciona while:

$ cat loop.sh #!/bin/bash count=10 while [ 1 = 1 ] do ((count++)) echo $count done $ ./loop.sh ... 5378 5379 5380 5381 5382 5383 ^C

Del mismo modo, pero en la dirección opuesta, el ciclo hasta también funciona:

$ cat loop.sh #!/bin/bash count=0 hasta que [ $count -gt 10 ] do ((count++)) echo $count done

Aquí establecemos una condición similar, pero en lugar de “hasta que la variable sea menor de 10”, indicamos “hasta que la variable sea mayor de 10”. Resultado de la ejecución:

$ ./bucle.sh 1 2 3 4 5 6 7 8 9 10 11

Si el ejemplo anterior de un "bucle infinito" se ejecuta usando hasta, no generará nada, a diferencia de while:

$ cat loop.sh #!/bin/bash count=10 hasta que [ 1 = 1 ] do ((count++)) echo $count done $ ./loop.sh $

Porque " condición» inicialmente « verdadero» - el cuerpo del bucle no se ejecutará.

Al igual que en el ciclo for, las funciones se pueden usar en while y till. Por ejemplo, un bucle de un script muy utilizado que comprueba el estado del servidor gato(PID se toma en el sistema SLES, puede diferir en otros sistemas), una versión ligeramente simplificada:

$ cat loop.sh #!/bin/bash check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(print $2)"` ) while check_tomcat_status do if [ -n "$ EJECUTAR"] luego printf "ADVERTENCIA: Tomcat aún se está ejecutando con PID $ EJECUTAR". else printf "Tomcat se detuvo, procediendo... nn" break fi done

Resultado de la ejecución:

$ ./loop.sh ADVERTENCIA: Tomcat aún se ejecuta con PID 14435 26548. ADVERTENCIA: Tomcat aún se ejecuta con PID 14435 26548. ADVERTENCIA: Tomcat aún se ejecuta con PID 14435 26548. ADVERTENCIA: Tomcat aún se ejecuta con PID 14435 26548. ADVERTENCIA: Tomcat aún se ejecuta con PID 14435 26548. ADVERTENCIA: Tomcat aún se ejecuta con PID 14435

Versión completa:

Check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(print $2)"` ) while check_tomcat_status; do if [ -n "$RUN" ] luego printf "ADVERTENCIA: Tomcat aún se está ejecutando con PID $RUN. ¿Detenerlo? " answer "Deteniendo Tomcat..." "Procediendo con la instalación..." && $CATALINA_HOME/bin/shutdown. sh 2&>1 /desarrollo/null || break sleep 2 if [ -n "$RUN" ] luego printf "Tomcat sigue ejecutándose. ¿Matarlo?" answer "Matando a Tomcat..." "Procediendo con la instalación...n" && kill $RUN || break sleep 2 fi else printf "Tomcat se detuvo, procediendo...nn" break fi done

La función de respuesta se describió en el artículo, pero aquí se usa una versión ligeramente mejorada:

Respuesta () (al leer la respuesta; hacer echo case $respuesta en |) printf "$1n" return 0 break ;; |) printf "$2n" devuelve 1 descanso ;; *) printf "¡Por favor, ingrese S (sí) o N (no)!" esac hecho)

Aquí era posible usar while y till, pero no el ciclo for, ya que for funcionaría una vez (obtener el PID y end).

para VAR en 1 2 3...N hacer hecho o en una línea: para VAR en 1 2 3...N; hacer ; hecho
Se permite sustituir tanto valores numéricos como caracteres ASCII en una variable.
Ejemplo: $ para i en 1 2 A B Abc ; hacer eco $i; hecho 1 2 A B Abc Un ejemplo de transferencia de archivos a una variable por "máscara" para la transcodificación de video: para i en*.avi; hacer ; hecho

2. Sustituir los resultados de ejecutar otro comando

para VAR en $(); hacer ; hecho
Un ejemplo del uso de los resultados del comando seq: para i en$(seq[CLAVE]); hacer echo $i; hecho$ para i en $(secuencia 3); hacer eco $i; hecho 1 2 3 $ para i en $(seq 3 5); hacer eco $i; hecho 3 4 5 $ para i en $(seq 2 2 6); hacer eco $i; hecho 2 4 6 Un ejemplo del uso de los resultados del comando ls: $ para i en $(ls /$HOME/Video); hacer eco $i; hecho 001.avi 002.avi 003.avi

3. Sustitución usando estilo C

para((EXPR1; EXPR2; EXPR3)) hacer <список команд> hecho para((i=1; yo<=3 ; i++)); hacer echo $i; hecho$ por ((i=1; i<=3 ; i++)); do echo $i; done 1 2 3 Подробнее о применении C-style в Bash

4. Enumeración con llaves (..)

La sintaxis (START..END) es compatible desde bash versión 3.0+, y desde bash versión 4.0+ la sintaxis (START..END..INCREMENT) es compatible:

para VAR en {..} hacer hecho o para VAR en {....} hacer hecho Ejemplos: $ para i en (1..3); hacer eco $i; hecho 1 2 3 o $ para i en (4..8..2); hacer eco $i; done 4 6 8 Es posible contar tanto para incrementos como para decrementos de valores: $ for i in (6..-4..3); hacer eco $i; hecho 6 3 0 -3

5. Sustitución de parámetros ( en "$@")

Ejecuta comandos para cada parámetro que se pasó al script. para VAR en $@ hacer hecho o en una línea: para VAR en $@; hacer ; hecho
Entonces, si crea un script test.sh #!/bin/sh para VAR en $@ hacer eco$var hecho luego al ejecutarlo con parámetros: $ ./test.sh param1 param2 param3 param1 param2 param3 Parte en$@ se puede omitir. Luego se reescribirá el script test.sh: #!/bin/sh para VAR hacer eco$var hecho
He aquí un par de ejemplos (con en y sin): $ función FUNC_1 ( para VAR en $@; hacer eco $VAR; hecho; ) $ FUNC_1 param1 param2 param3 param1 param2 param3 $ función FUNC_2 ( para VAR; hacer eco $VAR; hecho; ) $ FUNC_2 param1 param2 param3 param1 param2 param3

6. Aplicar continuar y romper en un bucle for

Para todas las construcciones anteriores, es posible usar los comandos "continuar" para pasar al siguiente elemento del bucle o "romper" para salir del bucle.

Ejemplo (terminar cuando i=6 y no ejecutar cuando i=3 e i=5): para yo en (1..8); hacer si[ $i -eq 6 ]; entonces romper; fi si[ $i -eq 3 ] || [ $i -eq 5 ]; entonces continuar; fi echo $i hecho Resultado de la ejecución: $ $ for i in (1..8); hacer \ > si [ $i -eq 6 ]; luego romper; fi; \ > si [ $i -eq 3 ] || [ $i -eq 5 ]; luego continúa; fi; \ > echo $i; \> hecho 1 2 4

Si nota un error, seleccione un fragmento de texto y presione Ctrl + Enter
COMPARTIR: