disown o como desacoplar procesos

En las últimas semanas he publicado diferentes artículos ínitimamente relacionados con la gestión de procesos. Has podido ver diferentes opciones para trabajar con procesos en segundo plano, o también como dejar un proceso corriendo aún después de haber cerrado el terminal desde el que lo habías iniciado, utilizando para ello nohup o también tmux. Este artículo también trata sobre otra herramienta que tienes a tu alcance para dejar un proceso funcionando aún incluso después de haber cerrado el terminal desde el que lo iniciaste. Sin embargo, en esta ocasión se trata de una herramienta que está disponible en Bash. Me refiero a disown.

Con disown puedes desacoplar una proceso del determinal desde el que fue lanzado. Por tanto, se trata de una herramienta ideal que te va a permitir, ejecutar un proceso vía ssh en otra máquina, y dejarlo funcionando aunque salgas de ese proceso.

Desacoplar procesos con disown

disown

disown es una herramienta que te permite quitar todos los procesos de la tabla de procesos activos. Es decir, estás desacoplando el proceso del terminal desde el que lo lanzaste.

Otra opción es utilizar la opción -h. Si utilizas esta opción, los procesos no se quitan de la tabla de procesos activos sino que se marca para que la señal SIGHUP no se envie al proceso. Esto es lo mismo que hacías en el artículo sobre nohup.

Para aclarar mejor los conceptos voy a utilizar el mismo ejemplo del artículo sobre procesos en segundo plano. Se trataba de un sencillo script implementado en Python que imprimía fecha y hora cada segundo.

Para ejecutarlo simplemente tienes que escribir la siguiente instrucción en el terminal,

python3 -u test.py > salida.txt

Una vez lo hayas lanzado, utiliza el atajo de teclado Ctrl+Z para enviarlo a segundo plano. Al hacerlo de esta forma se detine el proceso. Para iniciar el proceso en segundo plano utiliza bg %1 (suponiendo que solo tienes este proceso). Para saber todos los procesos que tienes en segundo plano, recuerda que tienes la utilidad jobs que viste en el artículo que te he mencionado anteriormente sobre procesos en segundo plano.

Así, en el ejemplo en cuestión, si sigues los pasos indicados, y ejecutas jobs, el resultado tiene que ser,

[1]+  Ejecutando              python3 -u test.py > temporal.txt &

Llegados a este punto, tienes dos opciones. Por un lado sería quitar el proceso de la tabla de procesos activos, de forma que al cerrar el terminal no se encontrará el proceso y por tanto no se le enviará la señal SIGHUP o la otra opión es indicar que no se le envíe la mencionada señal. En el primer caso tienes que ejecutar,

disown %1

Y en el segundo caso

disown -h %1

En el caso de que no le indiques ningún proceso en concreto la operación se realizará sobre el proceso en curso. Por el contrario si utilizas la opción -a indicas que te referieres a todos los procesos de la tabla. Mientras que si utilizas la opción -r solo te estás refiriendo a los procesos que están en ejecución.

Mas ejemplos

Para aclarar todo esto que me parece ha quedado un poco enrevesado he lanzado 5 procesos idénticos,

python3 -u test.py > temporal.txt &
python3 -u test.py > temporal.txt &
python3 -u test.py > temporal.txt &
python3 -u test.py > temporal.txt &
python3 -u test.py > temporal.txt &

Si ahora ejecutas el comando jobs el resultado que obtendrás es,

[1]   Ejecutando              python3 -u test.py > temporal.txt &
[2]   Ejecutando              python3 -u test.py > temporal.txt &
[3]   Ejecutando              python3 -u test.py > temporal.txt &
[4]-  Ejecutando              python3 -u test.py > temporal.txt &
[5]+  Ejecutando              python3 -u test.py > temporal.txt &

En el caso de que ejecutes disown, será equivalente a que ejecutes disown %5. Si vuelves a ejecutar disown, el proceso que quitarás de la tabla será el cuarto, y así sucesivamente.

Si por el contrario ejecutas disown -a, comprobarás que todos los procesos desaparecen de la tabla. Sin embargo, si ejecutas ps -ef | grep "python3 -u test.py", comprobarás que todos los procesos están en marcha.

Mata ahora todos los procesos y para probar el funcionamiento con la opción -r. Para matar esos procesos ejecuta la instrucción,

pkill -f "python3 -u test.py"

Una vez detenidos todos los procesos, vuelve a lanzar de nuevo esos 5 procesos. Una vez lanzado traete el número 3 a primer plano y detenlo utilizando para ello Ctrl+Z. Si ahora ejecutas jobs el resultado que tienes qe obtener será algo similar a lo que puedes ver a continuación,

[1]   Ejecutando              python3 -u test.py > temporal.txt &
[2]   Ejecutando              python3 -u test.py > temporal.txt &
[3]+  Detenido                python3 -u test.py > temporal.txt
[4]   Ejecutando              python3 -u test.py > temporal.txt &
[5]-  Ejecutando              python3 -u test.py > temporal.txt &

Si ahora ejecutas disown -ar, el resultado será que se habrán quitados todos los procesos que se estaban ejecutando de la tabla de procesos, y solo te quedará el que estaba detenido, tal y como puedes ver a continuación,

[3]   Detenido                python3 -u test.py > temporal.txt

Con este último ya puedes hacer lo que quieras, por ejemplo, puedes matar el proceso, kill %3. De esta forma ahora al ejecutar jobs no te aparecerá listado ningún proceso. Sin embargo, si ejecutas de nuevo un ps -ef | grep "python3 -u test", verás que tienes cuatro procesos activos, como ya te podías imaginar.

De nuevo para detener todos esos procesos puedes utilizar pkill.


Más información,

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *