La situación es la siguiente, tenemos una shell bash ejecutando un proceso cuyo tiempo de ejecución va a ser muy largo y necesitamos cerrar la shell, por supuesto no podemos parar el proceso y arrancarlo de nuevo. Para solucionar este problema podemos hacer uso de los comandos bg (recordad el artículo sobre gestión de trabajos en BASH (jobs, fg, bg, &… que escribí hace un tiempo) y disown.
Por ejemplo, tenemos este comando en ejecución que simplemente escribe algo en un fichero de texto cada dos segundos. Lo tenemos en primer plano (fg):
Nota: los paréntesis son porque ejecuto una sub-shell para que interprete todos los comandos (separados por «;» como un único comando.
$ (while true; do echo "prueba - `date`" >> test.txt; sleep 2; done)
Puedo ver que efectivamente escribe cada dos segundos ejecutando un tail al fichero:
$ tail -f test.txt prueba - Thu Apr 11 21:11:56 CEST 2013 prueba - Thu Apr 11 21:11:58 CEST 2013 prueba - Thu Apr 11 21:12:00 CEST 2013 prueba - Thu Apr 11 21:12:02 CEST 2013 prueba - Thu Apr 11 21:12:04 CEST 2013
Ahora le vamos a mandar una señal SIGSTOP al proceso. Esto lo detendrá temporalmente. Para ello usamos Ctrl + z «^z». En la misma shell de bash desde la que lo hemos parado vemos con el comando jobs que el proceso está parado:
$ jobs [1]+ Stopped ( while true; do echo "prueba - `date`" >> test.txt; sleep 2; done )
Ahora lo vamos a pasar a segundo plano (background) con el comando bg:
$ bg [1]+ ( while true; do echo "prueba - `date`" >> test.txt; sleep 2; done ) &
Y automáticamente el proceso seguirá funcionando, pero ahora ya en segundo plano:
$ tail -f test.txt prueba - Thu Apr 11 21:17:34 CEST 2013 prueba - Thu Apr 11 21:17:36 CEST 2013 prueba - Thu Apr 11 21:17:38 CEST 2013 prueba - Thu Apr 11 21:17:40 CEST 2013 prueba - Thu Apr 11 21:17:42 CEST 2013
Finalmente ejecutamos el comando disown para desasociar el comando a la shell en la que nos encontramos, ya podremos entonces cerrar con tranquilidad la terminal. Básicamente lo que hace este comando es evitar que se mande una señal SIGHUP al proceso cuando cerramos la shell:
$ disown