Espera de procesos en Linux

LinuxLinuxBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

Los procesos de Linux son componentes fundamentales del sistema operativo que ejecutan programas y realizan tareas. Al desarrollar scripts de shell, a menudo es necesario ejecutar múltiples procesos de forma concurrente y asegurarse de que se completen antes de continuar con las operaciones posteriores.

En este laboratorio, aprenderá sobre el comando wait en la programación de scripts de shell de Linux. Esta poderosa herramienta permite a los procesos padre pausar la ejecución hasta que sus procesos hijos en segundo plano hayan finalizado. Al dominar las técnicas de espera de procesos, puede crear scripts más eficientes que coordinen adecuadamente múltiples operaciones concurrentes.

Comprender la espera de procesos es esencial para la administración del sistema, la automatización y el desarrollo de scripts de shell robustos. Aprenderá cómo iniciar procesos en segundo plano, esperar a que se completen y manejar sus estados de salida para garantizar un flujo de ejecución confiable.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("Linux")) -.-> linux/FileandDirectoryManagementGroup(["File and Directory Management"]) linux(("Linux")) -.-> linux/ProcessManagementandControlGroup(["Process Management and Control"]) linux(("Linux")) -.-> linux/VersionControlandTextEditorsGroup(["Version Control and Text Editors"]) linux(("Linux")) -.-> linux/BasicFileOperationsGroup(["Basic File Operations"]) linux/BasicFileOperationsGroup -.-> linux/chmod("Permission Modifying") linux/FileandDirectoryManagementGroup -.-> linux/cd("Directory Changing") linux/ProcessManagementandControlGroup -.-> linux/wait("Process Waiting") linux/VersionControlandTextEditorsGroup -.-> linux/nano("Simple Text Editing") subgraph Lab Skills linux/chmod -.-> lab-271433{{"Espera de procesos en Linux"}} linux/cd -.-> lab-271433{{"Espera de procesos en Linux"}} linux/wait -.-> lab-271433{{"Espera de procesos en Linux"}} linux/nano -.-> lab-271433{{"Espera de procesos en Linux"}} end

Comprender los procesos de Linux y la ejecución en segundo plano

En este paso, aprenderá sobre los procesos de Linux y cómo ejecutar comandos en segundo plano utilizando el operador &.

¿Qué son los procesos de Linux?

Un proceso en Linux es una instancia de un programa en ejecución. Cada proceso tiene un Identificador de Proceso (PID, por sus siglas en inglés) único y se ejecuta de forma independiente de otros procesos. Cuando ejecuta un comando en la terminal, inicia un proceso.

Ejecutar procesos en segundo plano

Normalmente, cuando ejecuta un comando en la terminal, debe esperar a que se complete antes de poder ejecutar otro comando. Sin embargo, puede ejecutar un comando en segundo plano agregando un ampersand & al final del comando.

Vamos a probar esto:

  1. Navegue hasta el directorio de su proyecto:

    cd ~/project
  2. Cree un script simple que simule una tarea de larga duración:

    nano long_task.sh
  3. Agregue el siguiente contenido al script:

    #!/bin/bash
    echo "Starting long task with PID $$"
    sleep 5
    echo "Long task completed"
  4. Guarde el archivo presionando Ctrl+O, luego Enter, y salga con Ctrl+X.

  5. Haga el script ejecutable:

    chmod +x long_task.sh
  6. Ejecute el script normalmente:

    ./long_task.sh

    Verá una salida como esta:

    Starting long task with PID 1234
    Long task completed

    Note que tuvo que esperar a que el script se completara antes de recuperar el indicador de comando.

  7. Ahora ejecute el script en segundo plano:

    ./long_task.sh &

    Verá una salida como esta:

    [1] 1235
    Starting long task with PID 1235

    El [1] es el número de tarea, y 1235 es el PID. Note que recupera el indicador de comando inmediatamente.

  8. Después de aproximadamente 5 segundos, verá:

    Long task completed
    [1]+  Done                    ./long_task.sh

    Esto indica que el proceso en segundo plano se ha completado.

Cuando ejecuta un comando en segundo plano, la shell no espera a que se complete antes de permitirle ingresar más comandos. Esto es útil para ejecutar múltiples tareas de forma concurrente.

Uso del comando wait para sincronizar procesos

En este paso, aprenderá cómo utilizar el comando wait para sincronizar procesos, lo que hace que el proceso padre espere a que se completen los procesos en segundo plano.

¿Qué es el comando wait?

El comando wait se utiliza en scripts de shell para pausar la ejecución del script hasta que se hayan completado uno o más procesos en segundo plano. Esto es especialmente útil cuando es necesario asegurarse de que ciertas tareas finalicen antes de continuar con las operaciones posteriores.

Uso de wait sin argumentos

Cuando se utiliza sin argumentos, el comando wait espera a que se completen todos los procesos en segundo plano.

Vamos a crear un script que demuestre esto:

  1. Navegue hasta el directorio de su proyecto:

    cd ~/project
  2. Cree un nuevo script:

    nano wait_demo.sh
  3. Agregue el siguiente contenido al script:

    #!/bin/bash
    
    echo "Starting background tasks..."
    
    ## Start two background tasks
    ./long_task.sh &
    ./long_task.sh &
    
    echo "Waiting for all background tasks to complete..."
    wait
    echo "All background tasks have completed!"
  4. Guarde y salga del editor presionando Ctrl+O, luego Enter y, finalmente, Ctrl+X.

  5. Haga el script ejecutable:

    chmod +x wait_demo.sh
  6. Ejecute el script:

    ./wait_demo.sh

    Verá una salida similar a la siguiente:

    Starting background tasks...
    Starting long task with PID 1236
    Starting long task with PID 1237
    Waiting for all background tasks to complete...
    Long task completed
    Long task completed
    All background tasks have completed!

Note que el mensaje "All background tasks have completed!" solo aparece después de que ambas tareas largas hayan finalizado. Esto demuestra cómo el comando wait pausa el script hasta que se completen todos los procesos en segundo plano.

Uso de wait con un PID específico

También puede utilizar wait para esperar a un proceso específico proporcionando su PID:

  1. Cree otro script:

    nano wait_pid_demo.sh
  2. Agregue el siguiente contenido:

    #!/bin/bash
    
    echo "Starting background tasks..."
    
    ## Start two background tasks and capture their PIDs
    ./long_task.sh &
    pid1=$!
    
    ./long_task.sh &
    pid2=$!
    
    echo "First process PID: $pid1"
    echo "Second process PID: $pid2"
    
    echo "Waiting for the first task to complete..."
    wait $pid1
    echo "First task has completed!"
    
    echo "Waiting for the second task to complete..."
    wait $pid2
    echo "Second task has completed!"
  3. Guarde y salga del editor presionando Ctrl+O, luego Enter y, finalmente, Ctrl+X.

  4. Haga el script ejecutable:

    chmod +x wait_pid_demo.sh
  5. Ejecute el script:

    ./wait_pid_demo.sh

    La salida mostrará que el script espera a cada proceso individualmente.

La variable $! contiene el PID del proceso en segundo plano ejecutado más recientemente. Esto le permite capturar y utilizar posteriormente el PID con el comando wait.

Manejo del estado de retorno de wait

En este paso, aprenderá cómo capturar y manejar el estado de retorno del comando wait, que refleja el estado de salida de los procesos en segundo plano.

Comprender el estado de salida y de retorno

En Linux, cada comando devuelve un estado de salida cuando se completa. Un estado de salida de 0 generalmente indica éxito, mientras que un valor distinto de cero indica un error o algún tipo de fallo.

El comando wait devuelve el estado de salida del comando esperado. Si se esperan varios procesos, devuelve el estado de salida del último proceso que terminó.

Vamos a crear scripts para demostrar esto:

  1. Navegue hasta el directorio de su proyecto:

    cd ~/project
  2. Cree un script que tenga éxito:

    nano success_task.sh
  3. Agregue el siguiente contenido:

    #!/bin/bash
    echo "Starting success task"
    sleep 2
    echo "Success task completed successfully"
    exit 0 ## Exit with success status
  4. Guarde y salga presionando Ctrl+O, luego Enter y, finalmente, Ctrl+X. Luego, haga que sea ejecutable:

    chmod +x success_task.sh
  5. Cree un script que falle:

    nano fail_task.sh
  6. Agregue el siguiente contenido:

    #!/bin/bash
    echo "Starting fail task"
    sleep 3
    echo "Fail task encountered an error"
    exit 1 ## Exit with error status
  7. Guarde y salga presionando Ctrl+O, luego Enter y, finalmente, Ctrl+X. Luego, haga que sea ejecutable:

    chmod +x fail_task.sh
  8. Ahora, cree un script que capture el estado de espera:

    nano wait_status_demo.sh
  9. Agregue el siguiente contenido:

    #!/bin/bash
    
    echo "Running a successful background task..."
    ./success_task.sh &
    wait
    
    wait_status=$?
    echo "Wait returned with status: $wait_status"
    
    if [ $wait_status -eq 0 ]; then
      echo "The background task succeeded!"
    else
      echo "The background task failed with status: $wait_status"
    fi
    
    echo ""
    echo "Running a failing background task..."
    ./fail_task.sh &
    wait
    
    wait_status=$?
    echo "Wait returned with status: $wait_status"
    
    if [ $wait_status -eq 0 ]; then
      echo "The background task succeeded!"
    else
      echo "The background task failed with status: $wait_status"
    fi
  10. Guarde y salga presionando Ctrl+O, luego Enter y, finalmente, Ctrl+X. Luego, haga que sea ejecutable:

    chmod +x wait_status_demo.sh
  11. Ejecute el script:

    ./wait_status_demo.sh

    Verá una salida similar a la siguiente:

    Running a successful background task...
    Starting success task
    Success task completed successfully
    Wait returned with status: 0
    The background task succeeded!
    
    Running a failing background task...
    Starting fail task
    Fail task encountered an error
    Wait returned with status: 1
    The background task failed with status: 1

Esto demuestra cómo se puede utilizar el estado de retorno del comando wait para determinar si los procesos en segundo plano se completaron correctamente o no, lo cual es esencial para el manejo de errores en scripts de shell.

Completar una aplicación práctica

En este último paso, aplicará lo que ha aprendido para crear un script más complejo que simule un proceso de preparación del sistema. Este script coordinará múltiples tareas en segundo plano y se asegurará de que todas se completen correctamente antes de continuar.

Crear los scripts de preparación

Primero, crearemos dos scripts que simulen diferentes tareas de preparación:

  1. Navegue hasta el directorio de su proyecto:

    cd ~/project
  2. Cree el primer script de preparación:

    nano decorate_hall.sh
  3. Agregue el siguiente contenido:

    #!/bin/bash
    echo "Decorating the hall..."
    sleep 3
    echo "Hanging decorations..."
    sleep 2
    echo "Decoration complete."
    exit 0
  4. Guarde y salga presionando Ctrl+O, luego Enter y, finalmente, Ctrl+X. Luego, haga que sea ejecutable:

    chmod +x decorate_hall.sh
  5. Cree el segundo script de preparación:

    nano cook_feast.sh
  6. Agregue el siguiente contenido:

    #!/bin/bash
    echo "Preparing ingredients..."
    sleep 2
    echo "Cooking main dishes..."
    sleep 3
    echo "Preparing desserts..."
    sleep 1
    echo "Cooking complete."
    exit 0
  7. Guarde y salga presionando Ctrl+O, luego Enter y, finalmente, Ctrl+X. Luego, haga que sea ejecutable:

    chmod +x cook_feast.sh

Crear el script principal de coordinación

Ahora, creemos el script principal que coordinará estas tareas de preparación:

  1. Cree el script principal:

    nano prepare_feast.sh
  2. Agregue el siguiente contenido:

    #!/bin/bash
    
    echo "=== Preparation Ceremony Started ==="
    echo "Starting all preparation tasks..."
    
    ## Start the preparations in the background
    ./decorate_hall.sh &
    decoration_pid=$!
    
    ./cook_feast.sh &
    cooking_pid=$!
    
    echo "All tasks started. Waiting for completion..."
    
    ## Wait for decoration to finish
    wait $decoration_pid
    decoration_status=$?
    
    if [ $decoration_status -eq 0 ]; then
      echo "Decoration completed successfully."
    else
      echo "Error: Decoration failed with status $decoration_status"
      exit 1
    fi
    
    ## Wait for cooking to finish
    wait $cooking_pid
    cooking_status=$?
    
    if [ $cooking_status -eq 0 ]; then
      echo "Cooking completed successfully."
    else
      echo "Error: Cooking failed with status $cooking_status"
      exit 1
    fi
    
    ## All preparations completed successfully
    echo "=== All preparations completed successfully! ==="
    echo "The ceremony can now begin."
    
    ## Create a verification file to indicate successful completion
    echo "decoration_status=$decoration_status" > preparation_results.txt
    echo "cooking_status=$cooking_status" >> preparation_results.txt
    echo "overall_status=0" >> preparation_results.txt
    
    exit 0
  3. Guarde y salga presionando Ctrl+O, luego Enter y, finalmente, Ctrl+X. Luego, haga que sea ejecutable:

    chmod +x prepare_feast.sh
  4. Ejecute el script principal:

    ./prepare_feast.sh

    Verá la salida de todas las tareas de preparación ejecutándose de forma concurrente, y el script principal esperando a que cada una se complete antes de declarar el éxito general.

Comprender el script

Examinemos las partes clave del script principal:

  • Iniciamos cada tarea de preparación en segundo plano utilizando &
  • Capturamos el PID de cada tarea utilizando $!
  • Esperamos a que cada tarea se complete utilizando wait $pid
  • Comprobamos el estado de salida de cada tarea
  • Creamos un archivo de verificación con los resultados

Este enfoque nos permite:

  1. Ejecutar múltiples tareas de forma concurrente
  2. Monitorear el éxito/fallo de cada tarea
  3. Abortar el proceso general si alguna tarea individual falla
  4. Crear un registro de los resultados

Este es un patrón común en la administración de sistemas y los scripts de automatización, donde se deben coordinar y monitorear múltiples procesos.

Resumen

En este laboratorio, ha aprendido cómo administrar y sincronizar procesos de manera efectiva en Linux utilizando el comando wait. Esta habilidad importante le permite crear scripts de shell más sofisticados que pueden coordinar múltiples operaciones concurrentes.

Los conceptos clave que ha dominado incluyen:

  • Ejecutar procesos en segundo plano utilizando el operador &
  • Utilizar el comando wait para pausar la ejecución hasta que se completen los procesos en segundo plano
  • Esperar a procesos específicos por su PID
  • Capturar y manejar el estado de retorno del comando wait
  • Implementar manejo de errores para procesos en segundo plano
  • Coordinar múltiples tareas concurrentes en un escenario práctico

Estas habilidades son fundamentales para la administración de sistemas, la automatización y la escritura de scripts de shell en entornos Linux. Al administrar adecuadamente la sincronización de procesos, puede crear scripts más eficientes que aprovechen la concurrencia mientras mantienen la secuencia adecuada de operaciones dependientes.

Ya sea que esté desarrollando sistemas de compilación, scripts de implementación o herramientas de administración de sistemas, la capacidad de coordinar múltiples procesos es una habilidad esencial que le permitirá crear soluciones más poderosas y eficientes.