GNU/Linux >> Tutoriales Linux >  >> Linux

Aprenda secuencias de comandos Bash multihilo con GNU Parallel

Si está cansado de que sus scripts de Bash tarden una eternidad en ejecutarse, este tutorial es para usted. A menudo, puede ejecutar secuencias de comandos Bash en paralelo, lo que puede acelerar drásticamente el resultado. ¿Cómo? Usando la utilidad GNU Parallel, también llamada simplemente Parallel, ¡con algunos ejemplos útiles de GNU Parallel!

Parallel ejecuta scripts de Bash en paralelo a través de un concepto llamado subprocesamiento múltiple. Esta utilidad le permite ejecutar diferentes trabajos por CPU en lugar de solo uno, reduciendo el tiempo para ejecutar un script.

En este tutorial, aprenderá secuencias de comandos Bash de subprocesos múltiples con una tonelada de excelentes ejemplos de GNU Parallel.

Requisitos previos

Este tutorial estará lleno de demostraciones prácticas. Si tiene la intención de seguir, asegúrese de tener lo siguiente:

  • Una computadora con Linux. Cualquier distribución funcionará. El tutorial usa Ubuntu 20.04 ejecutándose en Windows Subsystem for Linux (WSL).
  • Iniciar sesión con un usuario con privilegios sudo.

Instalación de GNU paralelo

Para comenzar a acelerar los scripts de Bash con subprocesos múltiples, primero debe instalar Parallel. Así que empecemos por descargarlo e instalarlo.

1. Abra una terminal Bash.

2. Ejecute wget para descargar el paquete paralelo. El siguiente comando descarga la última versión (parallel-latest ) en el directorio de trabajo actual.

wget https://ftp.gnu.org/gnu/parallel/parallel-latest.tar.bz2

Si prefiere usar una versión anterior de GNU Parallel, puede encontrar todos los paquetes en el sitio de descarga oficial.

3. Ahora, ejecute el comando tar a continuación para desarchivar el paquete que acaba de descargar.

A continuación, el comando usa el x bandera para extraer el archivo, j para especificar que apunta a un archivo con un .bz2 extensión, y f para aceptar un archivo como entrada del comando tar. sudo tar -xjf parallel-latest.tar.bz2

sudo tar -xjf parallel-latest.tar.bz2

Ahora debería tener un directorio llamado parallel- con el mes, día y año del último lanzamiento.

4. Navegue a la carpeta de archivo del paquete con cd . En este tutorial, la carpeta de archivo del paquete se llama parallel-20210422 , Como se muestra abajo.

5. A continuación, cree e instale el binario GNU Parallel ejecutando los siguientes comandos:

./configure
 make
 make install

Ahora, verifique que Parallel se instaló correctamente comprobando la versión que está instalada.

parallel --version

Al ejecutar Parallel por primera vez, es posible que también vea un par de líneas aterradoras que muestran texto como perl: warning: . Esos mensajes de advertencia indican que Parallel no puede detectar su configuración regional y de idioma actual. Pero no te preocupes por esas advertencias por ahora. Aprenderá a corregir esas advertencias más adelante.

Configuración de GNU paralelo

Ahora que Parallel está instalado, ¡puede usarlo de inmediato! Pero primero, es importante configurar algunas configuraciones menores antes de comenzar.

Mientras aún está en su terminal Bash, acepte el permiso de investigación académica de GNU Parallel diciéndole a Parallel que lo citará en cualquier investigación académica especificando el citation parámetro seguido de will cite .

Si no desea admitir GNU o sus mantenedores, no es necesario aceptar citar para usar GNU Parallel.

parallel --citation
will cite

Cambie la configuración regional configurando las siguientes variables de entorno ejecutando las líneas de código a continuación. Establecer variables de entorno de idioma y configuración regional como esta no es un requisito. Pero GNU Parallel los comprueba cada vez que se ejecuta.

Si las variables de entorno no existen, Parallel se quejará de ellas cada vez como vio en la sección anterior.

Este tutorial asume que hablas inglés. También se admiten otros idiomas.

export LC_ALL=C man
export LANGUAGE=en_US
export LANG=en_US.UTF-8

Ejecución de comandos Ad-Hoc Shell

¡Comencemos ahora a usar GNU Parallel! Para empezar, aprenderá la sintaxis básica. Una vez que se sienta cómodo con la sintaxis, verá algunos ejemplos prácticos de GNU Parallel más adelante.

Para comenzar, cubramos un ejemplo súper simple de repetir los números del 1 al 5.

1. En su terminal Bash, ejecute los siguientes comandos. Emocionante, ¿verdad? Bash usa el comando echo para enviar los números del 1 al 5 a la terminal. Si pusiera cada uno de estos comandos en un script, Bash ejecutaría cada uno secuencialmente, esperando que termine el anterior.

En este ejemplo, está ejecutando cinco comandos que no toman casi nada de tiempo. Pero, imagine si esos comandos fueran scripts de Bash que realmente hicieran algo útil pero tardaran una eternidad en ejecutarse.

 echo 1
 echo 2
 echo 3
 echo 4
 echo 5

Ahora, ejecute cada uno de esos comandos al mismo tiempo con Parallel como se muestra a continuación. En este ejemplo, Parallel ejecuta el comando echo y lo designa el ::: , pasa ese comando a los argumentos, 1 , 2 , 3 , 4 , 5 . Los tres dos puntos le dicen a Parallel que está proporcionando información a través de la línea de comando en lugar de la canalización (más adelante).

En el siguiente ejemplo, pasó un solo comando a Parallel sin opciones. Aquí, como todos los ejemplos de Parallel, Parallel inició un nuevo proceso para cada comando utilizando un núcleo de CPU diferente.

# From the command line
 parallel echo ::: 1 2 3 4 5

Todos los comandos paralelos siguen la sintaxis parallel [Options] .

3. Para demostrar la entrada paralela de recepción de la canalización de Bash, cree un archivo llamado count_file.txt como abajo. Cada número representa el argumento que pasará al comando echo.

 1
 2
 3
 4
 5

4. Ahora, ejecuta el cat comando para leer ese archivo y pasar la salida a Parallel, como se muestra a continuación. En este ejemplo, el {} representa cada argumento (1-5) que se pasará a Parallel.

# From the pipeline cat count_file.txt | parallel echo {}

Comparación de Bash y GNU paralelo

En este momento, usar Parallel puede parecer una forma complicada de ejecutar comandos Bash. Pero el verdadero beneficio para usted es el ahorro de tiempo. Recuerde, Bash se ejecutará en un solo núcleo de CPU, mientras que GNU Parallel se ejecutará en varios a la vez.

1. Para demostrar la diferencia entre los comandos Bash secuenciales y los paralelos, cree un script Bash llamado test.sh con el siguiente código. Cree este script en el mismo directorio donde creó el count_file.txt en antes.

El siguiente script de Bash lee el count_file.txt archivo, duerme durante 1, 2, 3, 4 y 5 segundos, repite la duración del sueño en el terminal y termina.

#!/bin/bash
 nums=$(cat count_file.txt) # Read count_file.txt
 for num in $nums           # For each line in the file, start a loop
 do
     sleep $num             # Read the line and wait that many seconds
     echo $num              # Print the line
 done

2. Ahora, ejecute el script usando el time comando para medir cuánto tiempo tarda en completarse el script. Tardará 15 segundos.

time ./test.sh

3. Ahora, usa el time comando nuevamente para realizar la misma tarea, pero esta vez use Parallel para hacerlo.

El siguiente comando realiza la misma tarea, pero esta vez, en lugar de esperar a que se complete el primer ciclo antes de iniciar el siguiente, ejecutará uno en cada núcleo de CPU e iniciará tantos como pueda al mismo tiempo.

time cat count_file.txt | parallel "sleep {}; echo {}"

¡Conoce el simulacro!

Ahora es el momento de entrar en algunos ejemplos más reales de GNU Parallel. Pero, antes de hacerlo, primero debe conocer el --dryrun bandera. Esta bandera resulta útil cuando desea ver lo que sucederá sin que Parallel lo haga.

El --dryrun flag puede ser la verificación de cordura final antes de ejecutar un comando que no se comporta de la manera que pensaba. Desafortunadamente, si ingresa un comando que dañaría su sistema, ¡lo único que GNU Parallel le ayudará a hacer es dañarlo más rápido!

parallel --dryrun "rm rf {}"

Ejemplo #1 de GNU Parallel:descarga de archivos de la Web

Para esta tarea, descargará una lista de archivos de varias URL en la web. Por ejemplo, estas URL podrían representar páginas web que desea guardar, imágenes o incluso una lista de archivos de un servidor FTP.

Para este ejemplo, va a descargar una lista de paquetes de archivo (y los archivos SIG) del servidor FTP de GNU paralelo.

1. Cree un archivo llamado download_items.txt, tome algunos enlaces de descarga del sitio de descarga oficial y agréguelos al archivo separados por una nueva línea.

 https://ftp.gnu.org/gnu/parallel/parallel-20120122.tar.bz2
 https://ftp.gnu.org/gnu/parallel/parallel-20120122.tar.bz2.sig
 https://ftp.gnu.org/gnu/parallel/parallel-20120222.tar.bz2
 https://ftp.gnu.org/gnu/parallel/parallel-20120222.tar.bz2.sig

Podría ahorrar algo de tiempo usando la biblioteca Beautiful Soup de Python para eliminar todos los enlaces de la página de descarga.

2. Lea todas las URL de download_items.txt y pásalos a Parallel, que invocará wget y pasar cada URL.

cat download_items.txt | parallel wget {}

No olvides que {} en un comando paralelo es un marcador de posición para la cadena de entrada!

3. Tal vez necesite controlar la cantidad de subprocesos que GNU Parallel usa a la vez. Si es así, agregue el --jobs o -j parámetro al comando. El --jobs El parámetro limita el número de subprocesos que pueden ejecutarse simultáneamente al número que especifique.

Por ejemplo, para limitar Parallel a descargar cinco URL a la vez, el comando se vería así:

#!/bin/bash
 cat download_items.txt | parallel --jobs 5 wget {}

El --jobs El parámetro en el comando anterior se puede ajustar para descargar cualquier cantidad de archivos, siempre que la computadora en la que se ejecuta tenga esa cantidad de CPU para procesarlos.

4. Para demostrar el efecto del --jobs parámetro, ahora ajuste el número de trabajos y ejecute el time Comando para medir cuánto tiempo lleva cada ejecución.

 time cat download_items.txt | parallel --jobs 5 wget {}
 time cat download_items.txt | parallel --jobs 10 wget {}

Ejemplo #2 de GNU Parallel:Descomprimir paquetes de archivo

Ahora que tiene todos estos archivos de almacenamiento descargados del ejemplo anterior, ahora debe desarchivarlos.

Mientras se encuentra en el mismo directorio que los paquetes de archivo, ejecute el siguiente comando paralelo. Observe el uso del comodín (* ). Dado que este directorio contiene paquetes de archivos y los archivos SIG, debe decirle a Parallel que solo procese .tar.bz2 archivos.

sudo parallel tar -xjf ::: *.tar.bz2

¡Prima! Si está utilizando GNU paralelo de forma interactiva (no en un script), agregue el --bar para que Parallel le muestre una barra de progreso mientras se ejecuta la tarea.

Ejemplo #3 de GNU Parallel:Eliminación de archivos

Si ha seguido los ejemplos uno y dos, ahora debería tener muchas carpetas en su directorio de trabajo ocupando espacio. ¡Así que eliminemos todos esos archivos en paralelo!

Para eliminar todas las carpetas que comienzan con parallel- usando Parallel, enumere todas las carpetas con ls -d y canalice cada una de esas rutas de carpeta a Parallel, invocando rm -rf en cada carpeta, como se muestra a continuación.

Recuerda el --dryrun ¡bandera!

ls -d parallel-*/ | parallel "rm -rf {}"

Conclusión

Ahora puedes automatizar tareas con Bash y ahorrarte mucho tiempo. Lo que elijas hacer con ese tiempo depende de ti. Ya sea que ahorrar tiempo signifique salir del trabajo un poco antes o leer otra publicación de blog de ATA, es hora de regresar a su día.

Ahora piense en todos los scripts de ejecución prolongada en su entorno. ¿Cuáles puedes acelerar con Parallel?


Linux
  1. ¿Ejecutar scripts de Bash al ingresar a un directorio?

  2. Linux – ¿Argumento de par paralelo Gnu con argumentos de entrada de archivo?

  3. Parámetros especiales de Bash explicados con 4 scripts de Shell de ejemplo

  4. Parámetros posicionales de Bash explicados con 2 scripts de shell de ejemplo

  5. Valor porcentual con GNU Diff

Aprende Linux con la Raspberry Pi

Escribir comentarios en Bash Scripts

Cómo crear cuadros de diálogo GUI en Bash Scripts con Whiptail en Linux

Cómo crear documentos con scripts Bash

Cómo trabajar con declaraciones de casos en scripts Bash

Bash:esperar con tiempo de espera