Muchas veces olvido, que al contrario que yo, Linux es un sistema operativo multitarea. En este sentido, Linux está corriendo cientos de procesos de forma simultánea. No solo las aplicaciones que estás viendo o que estás utilizando, mas, muchas mas. Solo tienes que ejecutar el comando top
, o htop si lo prefieres, para que te hagas una idea de todo lo que está haciendo sin que tu apenas seas consciente. Se pueden ejecutar procesos en segundo plano en Linux.
En este sentido, tienes que aprovechar todas las posibilidades que te ofrece. Y aunque tu no seas multitarea, o por lo menos ese es mi caso, si que puedes sacarle partido a Linux, añadiendo una tarea tras otra. Sin embargo, a diferencia de ti, mientras que tu se las añades de forma secuencial, Linux puede procesarlas en paralelo. Así, puedes lanzar varios scripts en paralelo aprovechando el tutorial sobre scripts en Bash. Pero, ¿como iniciar varios scripts en paralelo?. La solución está en lanzarlos en segundo plano en Linux.
Así, en este artículo vas a ver como lanzar procesos en segundo plano desde un terminal. Como saber que procesos tienes corriendo en ese terminal, como recuperar un proceso, y pasarlo de segundo plano a primer plano, y por supuesto, como matar un proceso que está trabajando en segundo plano.
Procesos en segundo plano en Linux
¿Que es un proceso en segundo plano en Linux?
Cuando lanzas un comando en el terminal, por ejemplo ls
tienes que esperar hasta que termine. Por el contrario, un proceso que se ejecuta en segundo plano no interfiere en otras labores. Si lanzas un proceso en segundo plano desde un terminal, tu podrás continuar utilizando el terminal, mientras que este proceso se ejecuta por detrás, sin que tu seas consciente de lo que está sucediendo.
Un ejemplo
Para que puedas probar todo esto en primer plano, he escrito un sencillo script en Python, test.py
, que puedes ver a continuación,
#!/usr/bin/env python3
import time
import datetime
counter = 0
while True:
counter += 1
print('{0} - {1}'.format(counter, datetime.datetime.now()))
time.sleep(1)
Para ejecutar este script solo tienes que ejecutar esta instrucción en el terminal python3 test.py
. Lo único que hace este script es imprimir un número consecutivo cada segundo seguido de la fecha y hora a la que lo ha hecho. Esto de forma ininterrumpida hasta que tu lo detengas. Así, por ejemplo la salida puede ser algo como lo que ves a continuación,
1 - 2019-05-30 20:34:42.583360
2 - 2019-05-30 20:34:43.584496
3 - 2019-05-30 20:34:44.585719
Si lanzas este proceso de la forma habitual observarás que no puedes continuar utilizando el terminal. No lo puedes continuar utilizando porque este script en Python se ha apoderado del terminal. Hasta que no utilices el atajo de teclado Ctrl+C
no se detendrá.
jobs
Sin embargo, en lugar de utilizar Ctrl+C
prueba a utilizar Ctrl+Z
. Lo que hace este atajo de teclado es enviar el proceso a segundo plano. Sin embargo ha detenido el proceso, y aunque está en segundo plano, no está trabajando para ti, realmente está detenido. Fíjate lo que se muestra en el terminal,
^Z
[1]+ Detenido python3 test.py
Sin embargo, ahora ya puedes continuar utilizando el terminal. Para saber los procesos que tienes en segundo plano tienes que utilizar el comando jobs
. En mi caso, al hacerlo el resultado es el que ves a continuación,
$ jobs
[1]+ Detenido python3 test.py
Iniciar el proceso en segundo plano
Probablemente te estés preguntado como puedes lanzar el proceso para que se continué ejecutando. Sencillo, para iniciar un proceso directamente en segundo plano solo tienes que añadir &
al final de la instrucción. Por ejemplo, para el caso anterior,
python3 test.py &
Si, ya te has dado cuenta, que el script está imprimiendo el resultado directamente en el terminal, lo que hace que sea incómodo trabajar. Mi recomendación es que envíe la salida a un archivo en lugar de a la salida estándar. Esto se hace de forma sencilla, tal y como lo explico en el capítulo sobre redirigir entrada y salida, del tutorial sobre el terminal.
Sea como sea, el primer paso es detener el proceso. Pero lo tienes en segundo plano, ¿como lo recuperamos? Primero utiliza jobs
para saber el número de proceso, y posteriormente fg %
seguido del número de proceso. Fíjate,
$ jobs
[1]+ Detenido python3 test.py
[2]- Ejecutando python3 test.py &
$ fg %2
Una vez ya lo tienes en primer plano lo puedes detener como habitualmente, utilizando el atajo de teclado Ctrl+C
. Antes de avanzar con fg
y su reverso bg
, lanzaremos el proceso en segundo plano pero redirigiendo la salida a un archivo. Para hacer esto ejecuta la siguiente instrucción en el terminal,
python3 test.py > salida.out 2>&1 &
Ahora utiliza de nuevo jobs
para ver los procesos en segundo plano. Fíjate como lo tengo yo ahora,
$ jobs
[1]+ Detenido python3 test.py
[2]- Ejecutando python3 test.py > salida.out 2>&1 &
Como ves, el primero que inicié, hace varios párrafos, sigue detenido, mientras que el segundo se está ejecutando. El resultado lo puedes ver en salida.out
. Si quieres ver de forma continua lo que hace, ejecuta la instrucción que te indico a continuación, tal y como te indiqué en el capítulo sobre procesar texto del tutorial sobre el terminal.
$ tail -f salida.out
Cuando te canses de ver lo que está sucediendo, no tienes mas que utilizar el atajo de teclado Ctrl+C
para detenerlo.
fg y bg
Los comandos fg
y bg
te permitirán traer un proceso a primer plano o enviarlo a segundo plano respectivamente. Su uso es tan sencillo, como ejecutar la instrucción seguido de %
y el número del proceso que obtenemos de jobs
.
Así si quisieras traer el proceso 2 a primer plano, tan solo tienes que ejecutar fg %2
. Pero una vez en primer plano ¿como lo devuelves a segundo plano? Utilizando el atajo de teclado Ctrl+Z
.
Sin embargo al utilizar el atajo de teclado lo has detenido, y esa no era tu intención, tu querías que continuara. No hay problema, simplemente utiliza bg %2
y el proceso que se pondrá en marcha de nuevo.
Así la operativa ha sido,
- traer el proceso a primer plano utilizando
fg %2
- devolver el proceso a segundo plano con el atajo de teclado
Ctrl+Z
- poner el proceso en marcha una vez que está en segundo plano con
bg %2
.
Ahora, si ejecutas de nuevo jobs
te encontrarás en la siguiente situación,
$ jobs
[1]+ Detenido python3 test.py
[2]- Ejecutando python3 test.py > salida.out 2>&1 &
Ahora ya dominas perfectamente toda la operativa, puedes enviar un proceso a segundo plano, traerlo a primero, detenerlo, finalizarlo, ponerlo en marcha. ¿Pero que pasa si lo quieres finalizar directamente en segundo plano?
kill
Para finalizar un proceso que está en segundo plano tienes que utilizar kill %
seguido del número del proceso que quieres finalizar. Así, por ejemplo, si quisieras finalizar el proceso 1, la instrucción sería kill %1
.
Conclusión
La operativa es bastante sencilla, y te permite lanzar tantos procesos como necesites gestionándolos fácilmente con estas cuatro instrucciones,
jobs
para conocer los procesos en segundo planofg
te permite traer el proceso a primer planobg
puedes enviar el proceso a segundo planokill
para matar un proceso en segundo plano
Con esto puedes ir enviando uno u otro proceso a segundo plano, y recuperarlo cuando lo consideres.
Muchas gracias, me sirvio para lo que necesitaba
Muchas gracias!