Cómo ejecutar y controlar procesos en segundo plano en Linux

Utilice el shell Bash en Linux para administrar procesos en primer plano y en segundo plano. Puede usar las funciones y señales de control de trabajos de Bash para brindarle más flexibilidad en la forma en que ejecuta los comandos. Te mostramos cómo.

Todo sobre los procesos

Siempre que se ejecuta un programa en un sistema operativo Linux o similar a Unix, se inicia un proceso. «Proceso» es el nombre de la representación interna del programa en ejecución en la memoria de la computadora. Hay un proceso para cada programa activo. De hecho, existe un proceso para casi todo lo que se ejecuta en su computadora. Eso incluye los componentes de su entorno de escritorio gráfico (GDE) como GNOMO o KDEy sistema demonios que se lanzan al inicio.

¿Por qué casi todo lo que se está ejecutando? Bueno, Bash integrado como discos compactos, pwdy alias no es necesario tener un proceso iniciado (o «generado») cuando se ejecutan. Bash ejecuta estos comandos dentro de la instancia del shell Bash que se ejecuta en la ventana de su terminal. Estos comandos son rápidos precisamente porque no necesitan tener un proceso iniciado para que se ejecuten. (Puede escribir ayuda en una ventana de terminal para ver la lista de funciones integradas de Bash).

Los procesos se pueden ejecutar en primer plano, en cuyo caso se hacen cargo de su terminal hasta que se hayan completado, o se pueden ejecutar en segundo plano. Los procesos que se ejecutan en segundo plano no dominan la ventana de la terminal y puede continuar trabajando en ella. O al menos, no dominan la ventana de la terminal si no generan una salida de pantalla.

Un ejemplo desordenado

Empezaremos un simple ping seguimiento en ejecución. Vamos a hacer ping al dominio kirukiru.es. Esto se ejecutará como un proceso en primer plano.

ping www.howtogeek.com

ping www.howtogeek.com en una ventana de terminal

Obtenemos los resultados esperados, desplazándonos hacia abajo por la ventana del terminal. No podemos hacer nada más en la ventana del terminal mientras se ejecuta ping. Para terminar el comando presione Ctrl + C.

Ctrl+C

salida de rastreo de ping en una ventana de terminal

El efecto visible de Ctrl + C se resalta en la captura de pantalla. ping da un breve resumen y luego se detiene.

Repitamos eso. Pero esta vez presionaremos Ctrl + Z en lugar de Ctrl + C. La tarea no terminará. Se convertirá en una tarea en segundo plano. Obtenemos el control de la ventana de terminal que nos devuelve.

ping www.howtogeek.com
Ctrl+Z

efecto de Ctrl + Z en un comando que se ejecuta en una ventana de terminal

El efecto visible de presionar Ctrl + Z se resalta en la captura de pantalla.

Esta vez se nos dice que el proceso se detiene. Detenido no significa terminado. Es como un coche en una señal de alto. No lo hemos desechado y tirado. Todavía está en la carretera, parado, esperando para comenzar. El proceso ahora es un trabajo en segundo plano.

El comando de trabajos enumerará los trabajos que se han iniciado en la sesión de terminal actual. Y como los trabajos son (inevitablemente) procesos, también podemos usar el comando ps para verlos. Usemos ambos comandos y comparemos sus salidas. Usaremos la opción T (terminal) para enumerar solo los procesos que se están ejecutando en esta ventana de terminal. Tenga en cuenta que no es necesario utilizar un guión, con la opción T.

jobs
ps T

comando de trabajos en una ventana de terminal

El comando de trabajos nos dice:

  Cómo ejecutar un programa de Linux al inicio con systemd

[1]: El número entre corchetes es el número de trabajo. Podemos usar esto para referirnos al trabajo cuando necesitamos controlarlo con comandos de control del trabajo.
+: El signo más + muestra que este es el trabajo sobre el que se actuará si usamos un comando de control de trabajo sin un número de trabajo específico. Se llama trabajo predeterminado. El trabajo predeterminado es siempre el que se agregó más recientemente a la lista de trabajos.
Detenido: el proceso no se está ejecutando.
ping www.howtogeek.com: la línea de comando que inició el proceso.

El comando ps nos dice:

PID: el ID de proceso del proceso. Cada proceso tiene una identificación única.
TTY: el pseudo-teletipo (ventana de terminal) desde el que se ejecutó el proceso.
STAT: El estado del proceso.
TIEMPO: la cantidad de tiempo de CPU consumido por el proceso.
COMANDO: El comando que inició el proceso.

Estos son valores comunes para la columna STAT:

D: sueño ininterrumpido. El proceso se encuentra en un estado de espera, generalmente esperando entrada o salida, y no se puede interrumpir.
Yo: Inactivo.
R: Corriendo.
S: Sueño interrumpible.
T: Detenido por una señal de control de trabajo.
Z: Un proceso zombi. El proceso ha finalizado, pero su proceso principal no lo ha «limpiado».

El valor de la columna STAT puede ir seguido de uno de estos indicadores adicionales:

<: high-priority="" task="" nice="" to="" other="" processes="" n:="" low-priority="" l:="" process="" has="" pages="" locked="" into="" memory="" used="" by="" real-time="" s:="" a="" session="" leader.="" leader="" is="" that="" launched="" groups.="" shell="" multi-thread="" process.="" foreground="">Podemos ver que Bash tiene un estado de Ss. La «S» mayúscula nos dice que el shell Bash está durmiendo y es interrumpible. Tan pronto como lo necesitemos, responderá. La «s» minúscula nos dice que el shell es un líder de sesión.

El comando ping tiene el estado T. Esto nos dice que el ping ha sido detenido por una señal de control de trabajo. En este ejemplo, ese fue Ctrl + Z que usamos para ponerlo en segundo plano.

El comando ps T tiene un estado de R, que significa en ejecución. El + indica que este proceso es miembro del grupo de primer plano. Entonces, el comando ps T se está ejecutando en primer plano.

El comando bg

El comando bg se usa para reanudar un proceso en segundo plano. Se puede utilizar con o sin número de trabajo. Si lo usa sin un número de trabajo, el trabajo predeterminado pasa a primer plano. El proceso aún se ejecuta en segundo plano. No puede enviarle ninguna entrada.

Si emitimos el comando bg, reanudaremos nuestro comando ping:

bg

bg en una ventana de terminal

El comando ping se reanuda y vemos la salida de desplazamiento en la ventana del terminal una vez más. Se muestra el nombre del comando que se ha reiniciado. Esto se resalta en la captura de pantalla.

se reanudó el proceso de ping en segundo plano con salida en una viuda de terminal

Pero tenemos un problema. La tarea se está ejecutando en segundo plano y no acepta entradas. Entonces, ¿cómo lo detenemos? Ctrl + C no hace nada. Podemos verlo cuando lo escribimos, pero la tarea en segundo plano no recibe esas pulsaciones de teclas, por lo que sigue haciendo ping alegremente.

  Cómo hacer una copia de seguridad de la instalación de Linux

Tarea en segundo plano que ignora Ctrl + C en una ventana de terminal

De hecho, ahora estamos en un extraño modo combinado. Podemos escribir en la ventana de terminal, pero lo que escribimos es rápidamente barrido por la salida de desplazamiento del comando ping. Todo lo que escribimos tiene efecto en el primer plano.

Para detener nuestra tarea en segundo plano, debemos ponerla en primer plano y luego detenerla.

El comando fg

El comando fg traerá una tarea en segundo plano al primer plano. Al igual que el comando bg, se puede utilizar con o sin un número de trabajo. Usarlo con un número de trabajo significa que funcionará en un trabajo específico. Si se usa sin un número de trabajo, se usa el último comando que se envió al fondo.

Si escribimos fg, nuestro comando ping se pondrá en primer plano. Los caracteres que escribimos se mezclan con la salida del comando ping, pero el shell los opera como si se hubieran ingresado en la línea de comandos como de costumbre. Y de hecho, desde el punto de vista del caparazón Bash, eso es exactamente lo que ha sucedido.

fg

comando fg mezclado con la salida de ping en una ventana de terminal

Y ahora que tenemos el comando ping ejecutándose en primer plano una vez más, podemos usar Ctrl + C para matarlo.

Ctrl+C

Ctrl + C para detener el comando ping en una ventana de terminal

Necesitamos enviar las señales correctas

Eso no fue exactamente bonito. Evidentemente, ejecutar un proceso en segundo plano funciona mejor cuando el proceso no produce salida y no requiere entrada.

Pero, desordenado o no, nuestro ejemplo logró:

Poniendo un proceso en segundo plano.
Restaurar el proceso a un estado de ejecución en segundo plano.
Devolviendo el proceso al primer plano.
Terminando el proceso.

Cuando usa Ctrl + C y Ctrl + Z, está enviando señales al proceso. Estos son formas taquigráficas de usar el comando kill. Existen 64 señales diferentes que matar puede enviar. Use kill -l en la línea de comando para listarlos. kill no es la única fuente de estas señales. Algunos de ellos son generados automáticamente por otros procesos dentro del sistema.

Éstos son algunos de los más utilizados.

SIGHUP: Señal 1. Se envía automáticamente a un proceso cuando el terminal en el que se está ejecutando está cerrado.
SIGINT: Señal 2. Enviado a un proceso, presionas Ctrl + C. El proceso se interrumpe y se le indica que finalice.
SIGQUIT: Señal 3. Enviado a un proceso si el usuario envía una señal de salida Ctrl + D.
SIGKILL: Señal 9. El proceso se detiene inmediatamente y no intentará cerrarse limpiamente. El proceso no se desarrolla con gracia.
SIGTERM: Señal 15. Esta es la señal predeterminada enviada por kill. Es la señal de terminación de programa estándar.
SIGTSTP: Señal 20. Enviado a un proceso cuando usa Ctrl + Z. Detiene el proceso y lo pone en segundo plano.

Debemos usar el comando kill para emitir señales que no tengan combinaciones de teclas asignadas.

Mayor control del trabajo

Un proceso que se mueve a un segundo plano mediante Ctrl + Z se coloca en el estado detenido. Tenemos que usar el comando bg para que se vuelva a ejecutar. Iniciar un programa como un proceso en ejecución en segundo plano es sencillo. Agregue un ampersand & al final de la línea de comando.

  Cómo jugar Space Engineers en Linux

Aunque es mejor que los procesos en segundo plano no escriban en la ventana de la terminal, usaremos ejemplos que sí lo hacen. Necesitamos tener algo en las capturas de pantalla a lo que podamos hacer referencia. Este comando iniciará un ciclo sin fin como proceso en segundo plano:

mientras sea cierto; haz eco de «Cómo hacer el proceso de bucle geek»; dormir 3; hecho &

mientras sea cierto;  haz eco

Se nos dice el número de trabajo y el ID de identificación de proceso del proceso. Nuestro número de trabajo es 1 y la identificación del proceso es 1979. Podemos usar estos identificadores para controlar el proceso.

La salida de nuestro bucle sin fin comienza a aparecer en la ventana del terminal. Como antes, podemos usar la línea de comandos, pero los comandos que emitimos se intercalan con la salida del proceso de bucle.

ls

Salida del proceso de bucle en segundo plano intercalado con salida de otros comandos

Para detener nuestro proceso, podemos usar trabajos para recordarnos cuál es el número de trabajo y luego usar kill.

jobs informa que nuestro proceso es el trabajo número 1. Para usar ese número con kill debemos precederlo con un signo de porcentaje%.

jobs
kill %1

trabajos y matar a% 1 en una ventana de terminal

kill envía la señal SIGTERM, señal número 15, al proceso y se termina. La próxima vez que se presione la tecla Intro, se mostrará el estado del trabajo. Enumera el proceso como «terminado». Si el proceso no responde al comando kill, puede llevarlo a un nivel superior. Use kill con SIGKILL, señal número 9. Simplemente coloque el número 9 entre el comando kill y el número de trabajo.

kill 9 %1

Cosas que hemos cubierto

Ctrl + C: Envía SIGINT, señal 2, al proceso — si está aceptando entrada — y le dice que termine.
Ctrl + D: Envía SISQUIT, señal 3, al proceso, si está aceptando una entrada, y le dice que salga.
Ctrl + Z: Envía SIGSTP, señal 20, al proceso y le dice que se detenga (suspenda) y se convierta en un proceso en segundo plano.
trabajos: enumera los trabajos en segundo plano y muestra su número de trabajo.
bg job_number: reinicia un proceso en segundo plano. Si no proporciona un número de trabajo, se utiliza el último proceso que se convirtió en una tarea en segundo plano.
fg job_number: trae un proceso en segundo plano al primer plano y lo reinicia. Si no proporciona un número de trabajo, se utiliza el último proceso que se convirtió en una tarea en segundo plano.
commandline &: Agregar un ampersand & al final de una línea de comando ejecuta ese comando como una tarea en segundo plano, que se está ejecutando.
kill% job_number: Envía SIGTERM, señal 15, al proceso para terminarlo.
kill 9% job_number: Envía SIGKILL, señal 9, al proceso y lo termina abruptamente.