Scripting de bash y gestión de procesos multiprocesos en la línea de comandos

Scripting de bash y gestión de procesos multiprocesos en la línea de comandos

Las cosas que puedes hacer usando script bash son ilimitadas. Una vez que comience a desarrollar scripts avanzados, pronto descubrirá que comenzará a cumplir con los límites del sistema operativo. Por ejemplo, ¿su computadora tiene 2 hilos de CPU o más (muchas máquinas modernas tienen 8-32 hilos)? Si es así, es probable que se beneficie de las secuencias de comandos y la codificación de bash de múltiples hechos múltiples. Continúa leyendo y descubre por qué!

En este tutorial aprenderás:

  • Cómo implementar frases bash de múltiples subprocesos directamente desde la línea de comandos
  • Por qué la codificación multiprocesada casi siempre puede y aumentará el rendimiento de sus scripts
  • Cómo funcionan los procesos de fondo y primer plano y cómo manipular las colas de trabajo
Scripting y gestión de procesos de BASH multiproceso

Requisitos y convenciones de software utilizados

Requisitos de software y convenciones de línea de comandos de Linux
Categoría Requisitos, convenciones o versión de software utilizada
Sistema Independiente de la distribución, dependiente de la versión bash
Software Interfaz de línea de comandos de bash (intento)
Convenciones # - requiere que los comandos de Linux dados se ejecuten con privilegios raíz directamente como un usuario raíz o mediante el uso de sudo dominio
ps - Requiere que los comandos de Linux dados se ejecuten como un usuario regular no privilegiado

Cuando ejecute un script bash,, como máximo, usará un solo hilo de la CPU, a menos que inicie subshells/hilos. Si su máquina tiene al menos dos subprocesos de CPU, podrá maximizar los recursos de la CPU utilizando secuencias de comandos multiproceso en Bash. La razón de esto es simple; Tan pronto como se inicia un 'hilo' secundario (léase: subshell), entonces ese hilo posterior puede (y a menudo) usar un hilo de CPU diferente.

Suponga por un momento que tiene una máquina moderna con 8 o más hilos. ¿Puede comenzar a ver cómo si pudiéramos ejecutar el código? Ocho hilos paralelos, todos al mismo tiempo, cada uno con un hilo de CPU diferente (o compartido en todos los hilos), de esta manera se ejecutaría mucho más rápido que un único threaded. Proceso que se ejecuta en un solo hilo de la CPU (que puede estar compartido con otros procesos de ejecución)? Las ganancias realizadas dependerán un poco de lo que se está ejecutando, pero las ganancias habrán, casi siempre!

Entusiasmado? Excelente. Vamos a sumergirnos.

Primero debemos entender qué es una subshell, cómo se inicia, por qué usaría uno y cómo se puede usar para implementar el código de bash de múltiples subprocesos.

Una subshell es otro proceso de cliente bash ejecutado/iniciado desde el actual. Hagamos algo fácil y comencemos uno desde un mensaje de terminal bash abierto:

$ bash $ salga de salida $ 

Que pasó aquí? Primero comenzamos otro shell de Bash (intento) que comenzó y a su vez arrojó un símbolo del sistema (ps). Entonces el segundo ps En el ejemplo anterior es en realidad un caparazón bash diferente, con una Pid (Pid es el identificador del proceso; Un identificador de número único que identifica de manera única cada proceso en ejecución en un sistema operativo). Finalmente salimos de la subshell a través de salida y regresó a la subshell principal! ¿Podemos probar de alguna manera esto es realmente lo que pasó?? Sí:

$ echo $ 220250 $ bash $ echo $ 222629 $ salida de salida $ echo $ 220250 $ 

Hay una variable especial en Bash $$, que contiene el Pid del shell actual en uso. ¿Puedes ver cómo cambió el identificador del proceso una vez que estuvimos dentro de una subshell??

Excelente! Ahora que sabemos qué son las subshells y un poco sobre cómo funcionan, vamos a sumergirnos en algunos ejemplos de codificación de múltiples subprocesos y aprender más!

Simple múltiple subproceso en Bash

Comencemos con un simple ejemplo de múltiples subprocesos de una línea, del cual la salida puede parecer algo confusa al principio:

$ para i en $ (SEQ 1 2); hacer eco $ i; hecho 1 2 $ para i en $ (SEQ 1 2); do echo $ i & doe [1] 223561 1 [2] 223562 $ 2 [1]- Hecho echo $ i [2]+ hecho echo $ i $ 

En el primero para bucle (consulte nuestro artículo sobre Bash Loops para aprender a codificar los bucles
), simplemente generamos la variable $ I que oscilará entre 1 y 2 (debido a nuestro uso del comando SEQ), que, curiosamente, se inicia en una subshell!

NOTA
Puedes usar el ps sintaxis en cualquier lugar Dentro de una línea de comando para iniciar una subshell: es una forma muy potente y versátil de codificar subshells directamente en otras líneas de comando!

En el segundo para bucle, hemos cambiado solo un personaje. En lugar de usar ; - un modismo de sintaxis Bash EOL (Fin de la línea) que termina un comando dado (puede pensar en ello como Enter/Execute/Adelante), usamos Y. Este simple cambio lo convierte en un programa casi completamente diferente, y nuestro código ahora es multiproceso! Ambos Echo procesarán más o menos al mismo tiempo, con un pequeño retraso en el sistema operativo que aún tiene que ejecutar la segunda ejecución de bucle (para eco '2').

Puedes pensar en Y de manera similar a ; con la diferencia que Y le dirá al sistema operativo que "siga ejecutando el siguiente comando, siga procesando el código" mientras ; esperará el comando de ejecución actual (terminado por ;) para terminar / finalizar antes de volver al símbolo del sistema / antes de continuar procesando y ejecutar el siguiente código.

Examinemos ahora la salida. Vemos:

[1] 223561 1 [2] 223562 $ 2 

Al principio, seguido de:

[1]- Hecho echo $ i [2]+ hecho echo $ i $ 

Y también hay una línea vacía en el medio, que es el resultado de procesos de fondo que aún se ejecutan mientras esperan la siguiente entrada de comando (intente este comando varias veces en la línea de comando, así como algunas variaciones de luz, y obtendrá un Siente cómo funciona).

La primera salida ([1] 223561) nos muestra que se inició un proceso de fondo, con PID 223561 y el número de identificador 1 fue dado a eso. Luego, ya antes de que el script alcanzara el segundo eco (un eco probablemente sea una declaración de código costosa para ejecutarse), la salida 1 fue mostrado.

Nuestro proceso de fondo no terminó por completo ya que la siguiente salida indica que comenzamos una segunda subshell/hilo (como lo indica [2]) con pid 223562. Posteriormente, el segundo proceso genera el 2 ("Indicativamente": los mecanismos del sistema operativo pueden afectar esto) antes de que el segundo hilo finalice.

Finalmente, en el segundo bloque de salida, vemos que los dos procesos terminan (como lo indican Hecho), así como lo que estaban ejecutando por última vez (como lo indicó echo $ i). Tenga en cuenta que los mismos números 1 y 2 se utilizan para indicar los procesos de fondo.

Más múltiples subprocesos en Bash

A continuación, ejecutemos tres comandos de sueño, todo terminado por Y (para que comiencen como procesos de fondo), y nos permitan variar sus longitudes de duración del sueño, por lo que podemos ver más claramente cómo funciona el procesamiento de fondo.

$ Sleep 10 & Sleep 1 & Sleep 5 & [1] 7129 [2] 7130 [3] 7131 $ [2]- Duerme el sueño 1 $ [3]+ Hecho Sleep 5 $ [1]+ Hecho Dormir 10 

La salida en este caso debe explicarse por sí misma. La línea de comando regresa inmediatamente después de nuestro dormir 10 y dormir 1 y dormir 5 y comando, y 3 procesos de fondo, con sus respectivos pid's se muestran. Llegué a Enter varias veces en el medio. Después de 1 segundo, el primer comando completó produciendo el Hecho Para el identificador de proceso [2]. Posteriormente, el tercer y primer proceso terminó, de acuerdo con sus respectivas duraciones del sueño. También tenga en cuenta que este ejemplo muestra claramente que múltiples trabajos se están ejecutando efectivamente, simultáneamente, en segundo plano.

Es posible que también hayas recogido el + Iniciar sesión en los ejemplos de salida anteriores. Esto se trata de control de trabajo. Veremos el control de trabajo en el próximo ejemplo, pero por el momento es importante entender que + indica que es el trabajo que se controlará si tuviéramos que usar/ejecutar los comandos de control de trabajo. Siempre es el trabajo que se agregó a la lista de trabajos en ejecución más recientemente. Este es el trabajo predeterminado, que siempre es el más recientemente agregado a la lista de trabajos.

A - indica el trabajo que se convertiría en el próximo valor predeterminado para los comandos de control de trabajo si el trabajo actual (el trabajo con el + signo) terminaría. El control del trabajo (o en otras palabras; el manejo de hilos de fondo) puede sonar un poco desalentador al principio, pero en realidad es muy útil y fácil de usar una vez que te acostumbras. Vamos a sumergirnos!

Control de trabajo en Bash

$ Sleep 10 & Sleep 5 & [1] 7468 [2] 7469 $ Jobs [1]- Running Sleep 10 y [2]+ Running Sleep 5 & $ FG 2 Sleep 5 $ FG 1 Sleep 10 $ 

Aquí colocamos dos durmientes en el fondo. Una vez que se iniciaron, examinamos los trabajos actualmente en ejecución utilizando el trabajos dominio. A continuación, el segundo hilo se colocó en primer plano usando el FG Comando seguido del número de trabajo. Puedes pensarlo así; el Y en el dormir 5 El comando se convirtió en un ;. En otras palabras, un proceso de fondo (no esperado) se convirtió en un proceso de primer plano.

Luego esperamos el dormir 5 comandar finalizar y posteriormente colocar el Dormir 10 comandar en primer plano. Tenga en cuenta que cada vez que hicimos esto tuvimos que esperar a que finalice el proceso de primer plano antes de recibir nuestra línea de comando, que no es el caso cuando se usa solo procesos de fondo (ya que literalmente se 'ejecutan en segundo plano')).

Control de trabajo en Bash: interrupción laboral

$ Sleep 10 ^Z [1]+ Deting Sleep 10 $ Bg 1 [1]+ Sleep 10 & $ FG 1 Sleep 10 $ 

Aquí presionamos CTRL+Z para interrumpir un sueño 10 (que se detiene como lo indica Interrumpido). Luego colocamos el proceso en el fondo y finalmente lo colocamos en primer plano y esperamos a que termine.

Control de trabajo en Bash: interrupción laboral

$ Sleep 100 ^Z [1]+ Deting Sleep 100 $ Kill %1 $ [1]+ Dormir terminado 100 

Habiendo comenzado 100 segundos dormir, A continuación, interrumpimos el proceso de ejecución de Ctrl+Z, y luego matamos el primer proceso de fondo iniciado/ejecutado utilizando el matar dominio. Tenga en cuenta cómo usamos %1 En este caso, en lugar de simplemente 1. Esto se debe a que ahora estamos trabajando con una utilidad que no está vinculada de forma nativa a los procesos de fondo, como FG y BG son. Por lo tanto, para indicar que matamos que queremos efectuar el primer proceso de fondo, usamos De % seguido del número de proceso de fondo.

Control de trabajo en Bash: proceso de reposo de proceso

$ Sleep 100 ^Z [1]+ STOPT DIEST 100 $ BG %1 [1]+ Sleep 100 & $ Deghus 

En este último ejemplo, nuevamente terminamos una carrera dormir, y colóquelo en el fondo. Finalmente ejecutamos el renegar de Comando que puede leer como: DisSociar todos los procesos de fondo (trabajos) desde el shell actual. Seguirán funcionando, pero ya no son 'propiedad' por el shell actual. Incluso si cierra su caparazón actual y cierre de sesión, estos procesos se seguirán funcionando hasta que terminen naturalmente.

Esta es una forma muy poderosa de interrumpir un proceso, colocarlo en el fondo, repudiarlo y luego inicio de sesión desde la máquina que estaba utilizando, siempre que ya no necesitará interactuar con el proceso. Ideal para esos procesos de larga duración sobre SSH que no se pueden interrumpir. Simplemente ctrl+z el proceso (que lo interrumpe temporalmente), colóquelo en el fondo, repude todos los trabajos y cierre sesión! Vaya a casa y tenga una noche agradable y relajada sabiendo que su trabajo seguirá corriendo!

Ejemplos de la línea de comandos de gestión de procesos y secuencias de comandos de scripting y gestión de procesos multiproceso

Conclusión

En este tutorial, vimos cómo implementar frases bash de múltiples subprocesos directamente desde la línea de comandos, y exploramos por qué la codificación múltiple a menudo aumenta el rendimiento de sus scripts. También examinamos cómo funcionan los procesos de fondo y primer plano, y manipulamos colas de trabajo. Finalmente exploramos cómo repudiar nuestra cola de trabajo del proceso actual, proporcionándonos un control adicional sobre los procesos de ejecución. Disfrute de sus nuevas habilidades encontradas y déjenos un comentario a continuación con sus experiencias de control de trabajo!

Tutoriales de Linux relacionados:

  • Una introducción a la automatización, herramientas y técnicas de Linux
  • Cosas para instalar en Ubuntu 20.04
  • Cosas que hacer después de instalar Ubuntu 20.04 fossa focal Linux
  • Mastering Bash Script Loops
  • Gestión de procesos de fondo bash
  • Bucles anidados en guiones Bash
  • Ubuntu 20.04 Guía
  • Cosas que hacer después de instalar Ubuntu 22.04 Jellyfish de Jammy ..
  • Ejemplos de consejos y trucos de comandos de comandos útiles - Parte 6
  • Tutorial de depuración de GDB para principiantes