bash - run - terminal open background process
¿Cuál es la forma más fácil de "separar/demonizar" un guión de Bash? (8)
Lo que intento hacer es escribir un script Bash que duerma durante un tiempo determinado antes de usar el comando mac say para hablar un poco de texto.
Me gustaría poder ejecutar el comando y luego cerrar el terminal para que siga hablando a la hora establecida. Miré en nohup, detach, launchd y poniendo el proceso en segundo plano, pero todas estas soluciones aún dan como resultado que el proceso finalice una vez que se cierra la terminal. ¿Debo de alguna manera hacer algún tipo de proceso infantil zombie para hacer esto? ¿Cuál es la mejor solución? Gracias
# Simple Example of main code
sleep 10;
say hello;
exit;
Dependiendo de su definición de ''fácil'' la respuesta puede ser daemon .
La Sección 3.7.6 del Manual de Bash dice:
El shell sale por defecto al recibir un SIGHUP. Antes de salir, un shell interactivo reenvía el SIGHUP a todos los trabajos, ejecutándose o deteniéndose. Los trabajos detenidos se envían a SIGCONT para garantizar que reciban el SIGHUP. Para evitar que el shell envíe la señal SIGHUP a un trabajo en particular, debe eliminarse de la tabla de trabajos con el comando interno de rechazo (ver Sección 7.2 [Builtins de Control de trabajos], página 88) o marcarse para no recibir SIGHUP con
disown -h
.
Entonces, usar nohup
o disown
debería hacer el truco. O puedes hacer:
trap "" 1
sleep 10
say hello
Esa línea '' trap
'' ignora la señal 1, SIGHUP; probablemente también puedas escribir '' trap "" HUP
''.
Necesitas usar nohup y fondo juntos. Acabo de probar esto en OS-X para verificar que funciona:
nohup ./say-hello.sh &
Si no lo comienzas con nohup
, como ya se sugirió, necesitarías usar el disown
como tal ...
$ ./say-hello.sh &
[1] 12345
$ disown -h %1
Tendrá que anotar el número del trabajo (la segunda línea en el ejemplo anterior, el número del trabajo está entre corchetes y el otro es la identificación del proceso) para que pueda pasarlo a disown
.
Tu script podría verse así:
#!/bin/bash
read -p "Text: " text
read -p "Delay: " delay
nohup bash -c "sleep $delay; say /"$text/" &"
Entonces ejecutarías tu script normalmente:
$ your_script
Text: hello
Delay: 10
y el script externo saldría, pero el Sleep&Say™
se dejaría ejecutándose en segundo plano.
Use nohup yourscript.sh &
como sugirió Piskvor.
Sin embargo, tenga en cuenta que no podrá recuperar el "control" de su proceso. Por lo tanto, si lo necesita, le sugiero que agregue el registro a un archivo para que sepa qué está haciendo su programa.
Matar tu programa podría no ser posible sin kill -9
, y eso podría ser un poco brutal. Si no quieres eso, te sugiero agrupar un archivo como end.txt
cada minuto más o menos. Si su programa detecta la presencia de dicho archivo en su directorio de trabajo, debe salir con gracia.
nohup yourscript.sh 10 "hello" &
# ^your script ^^your parameter 1
# ^^^^^^^your parameter 2
Esto separará la secuencia de comandos de la terminal y no se eliminará cuando la terminal se cierre. Tenga en cuenta el &
al final; puede pasar parámetros a su script normalmente. Entonces yourscript.sh podría ser:
#!/bin/bash
sleep $1;
say "$2";
exit;
Todas las soluciones aquí son muy buenas, pero no proporcionan una manera fácil de "ver" lo que sucede en el programa sin hacer una redirección que llene el disco duro.
Con la screen
, puede ejecutar fácilmente un script, cerrar su sesión de terminal / ssh, y luego regresar y "adjuntar" de nuevo al script. Hazlo, es bastante fácil.
Instalar
Primera screen
instalación:
sudo apt-get install screen
Despegar
y luego poner en su archivo bash
#!/usr/bin/env bash
screen -S myscreen -d -m bash -c ''ls; exec bash''
(reemplace ls
con su programa) myscreen
( -S
) una "pantalla" llamada myscreen
, y la separará ( -d
) ejecutando los comandos dentro de la opción `` -c```. Luego, si desea conectarse más tarde a esta pantalla:
Y adjuntar más tarde
screen -rd myscreen
si quiere listar toda la pantalla que se está ejecutando actualmente:
screen -ls
NB: si desea cerrar la pantalla cuando haya terminado, elimine el bash
al final del comando.