Hoy vamos a ver el modo de controlar jobs, procesos o aplicaciones que corren dentro de un sistema Linux/Unix. El objetivo es aprender a gestionar un proceso en ejecución pasandolo a segundo plano, suspenderlo, activarlo, desasociarlo de la shell, pararlo, etc.
Ejecutar un trabajo/proceso en segundo plano
Para ejecutar un proceso en segundo plano, debemos utilizar el carácter & y colocarlo al final del comando o proceso a ejecutar:
$ /var/tmp/foo.sh &
Recomendable revisar como valor añadido la entrada sobre el comando nohup, al igual que «disown» (ver final de la entrada) permite que la ejecución del proceso se mantenga pese a abandonar la shell/terminal.
Suspender un proceso que tenemos corriendo en primer plano
Si estamos ejecutando un trabajo en la shell/pantalla/terminal y queremos detener temporalmente su ejecución utilizaremos la combinación de teclas Ctrl + Z. Automáticamente nos asignará el ID de trabajo para poder gestionar el proceso posteriormente:
$ tail -2f /var/log/syslog Nov 9 19:27:53 Xubuntu kernel: [ 3327.578060] type=1701 audit(1415557673.161:887): Nov 9 19:27:53 Xubuntu kernel: [ 3327.581346] type=1701 audit(1415557673.165:888): ^Z [1]+ Stopped tail -2f /var/log/syslog
Utilizamos ese identificador (%1) para volver a ejecutarlo en primer plano:
$ fg %1
Si lo que queremos es seguir ejecutandolo pero en background/segundo plano en lugar de «fg» utilizamos «bg»:
$ bg %1
Esto es realmente útil en situaciones como la ejecución de un script que se demora más de lo esperado y necesitamos ejecutarlo sin necesidad de una terminal, lo dejamos en segundo plano y seguirá corriendo sin necesidad de ningún entorno visual. Útil si solo disponemos de una única terminal y necesitamos realizar varias tareas simultaneamente. En el caso de que queramos cerrar la sesión de shell es necesario utilizar el método del final del artículo.
Ejecutar en background los procesos suspendidos
Como hemos visto en el ejemplo anterior, podemos pasar a segundo plano los procesos suspendidos simplemente ejecutando «bg» o pasando como parámetro el identificador del proceso anteponiendole «%».
$ bg [1]+ top &
$ fg %6 tail -5f /var/log/syslog
Ejecutar en primer plano los procesos que se encuentran en background.
Para ello utilizaremos el comando fg
(foreground) junto con el ID del trabajo anteponiéndole %:
$ fg %1
Visualizar todos los procesos en primer plano, suspendidos, en segundo plano
El comando jobs
nos permite visualizar el listado de jobs/procesos en el sistema junto con su estado e identificador:
$ jobs [1]- Stopped top [2]+ Stopped watch "netstat -natp" [3] Running tail -f /var/log/syslog &
Un resumen práctico sería el siguiente: arrancar un programa (por ejemplo thunderbird) desde línea de comandos:
$ thunderbird
Necesitamos pararlo temporalmente así que en la terminal desde la que lo hemos lanzado presionamos Ctrl + Z.
$ thunderbird ^Z [1]- Stopped thunderbird $ jobs [1]- Stopped thunderbird
Ahora el programa está suspendido (signo -) a la espera de que hagamos algo con él, ya sea ponerlo en primer o segundo plano, pararlo…
Podemos arrancarlo de nuevo pero en background:
$ bg %1 [1]+ thunderbird &
En ese caso el signo – pasa a ser + ya que no está suspendido sino en ejecución (pero en segundo plano)
Y también podríamos pasarlo a primer plano:
$ fg %1
Parar o matar un proceso suspendido o en segundo plano
Si lo que queremos hacer es terminar la ejecución del proceso, podemos utilizar el comando «kill» con la peculiaridad de que le podemos pasar en lugar del PID el identificador de job:
$ jobs [1]- Stopped top [2]+ Stopped watch "netstat -natp" [3] Running tail -f /var/log/syslog &
$ kill %3
$ jobs [1]- Stopped top [2]+ Stopped watch "netstat -natp" [3] Terminated tail -f /var/log/syslog
$ jobs [1]- Stopped top [2]+ Stopped watch "netstat -natp"
Poner un proceso en segundo plano y desasociarlo de la shell
Para esta situación creé una entrada aparte que podéis leer al detalle en el siguiente enlace: Poner un proceso en segundo plano y desasociarlo de la shell. Básicamente jugamos con los comandos bg y disown. Esta secuencia nos permite poner un proceso en segundo plano y desasociarlo de la shell en la que estamos trabajando. Esto nos permite cerrar la sesión y que el proceso se siga ejecutando sin estar asociado a nuestra sesión.
Os recomiendo leer el artículo, el resumen es el siguiente:
Ejecutar un comando o script:
$ (while true; do echo "`date`" >> fecha.tmp; sleep 2; done)
El comando escribe la fecha cada 2 segundos en el fichero fecha.tmp:
$ tail -5 fecha.tmp Sun Nov 9 19:08:07 CET 2014 Sun Nov 9 19:08:09 CET 2014 Sun Nov 9 19:08:11 CET 2014
El proceso está en primer plano así que lo suspendemos mandandole la señal SIGSTOP usando Ctrl + z «^z»
$ (while true; do echo "`date`" >> fecha.tmp; sleep 2; done) ^Z [1]+ Stopped ( while true; do echo "`date`" >> fecha.tmp; sleep 2; done )
Ahora mismo en el log ya no se escribe la fecha cada 2 segundos, el proceso está suspendido. Para que siga funcionando, pero en segundo plano (bg) ejecutamos «bg»:
$ bg [1]+ ( while true; do echo "`date`" >> fecha.tmp; sleep 2; done ) &
A partir de ese momento el proceso vuelve a estar en ejecución pero en segundo plano y vuelve a escribir la fecha cada 2 segundos en el log. Si cerramos la terminal/shell, el proceso se parará. Para evitar esto ejecutamos «disown» y el proceso ya no dependerá de nuestra shell/terminal y podremos cerrar la ventana sin perder la ejecución:
$ disown