Tengo un script bash que inicia un script python3 (llamémoslo startup.sh
), con la línea clave:
nohup python3 -u <script> &
Cuando entro ssh
directamente y llamo a este script, el script de Python continúa ejecutándose en segundo plano después de salir. Sin embargo, cuando ejecuto esto:
ssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> "./startup.sh"
El proceso termina tan pronto como ssh
haya terminado de ejecutarse y cierra la sesión.
¿Cuál es la diferencia entre los dos?
EDIT: El script en Python, se está ejecutando un servicio web a través de la botella.
EDIT2: también intenté crear un script de inicio que startup.sh
ejecuta y ejecuta ssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> "sudo service start <servicename>"
, pero obtuve el mismo comportamiento.
EDITAR3: Tal vez sea algo más en el guión. Aquí está la mayor parte del guión:
chmod 700 ${key_loc}
echo "INFO: Syncing files."
rsync -azP -e "ssh -i ${key_loc} -o StrictHostKeyChecking=no" ${source_client_loc} ${remote_user}@${remote_hostname}:${destination_client_loc}
echo "INFO: Running startup script."
ssh -i ${key_loc} -o StrictHostKeyChecking=no ${remote_user}@${remote_hostname} "cd ${destination_client_loc}; chmod u+x ${ctl_script}; ./${ctl_script} restart"
EDIT4: Cuando ejecuto la última línea con un sueño al final:
ssh -i ${key_loc} -o StrictHostKeyChecking=no ${remote_user}@${remote_hostname} "cd ${destination_client_loc}; chmod u+x ${ctl_script}; ./${ctl_script} restart; sleep 1"
echo "Finished"
Nunca llega echo "Finished"
, y veo el mensaje del servidor Botella, que nunca vi antes:
Bottle vx.x.x server starting up (using WSGIRefServer())...
Listening on <URL>
Hit Ctrl-C to quit.
Veo "Terminado" si manualmente SSH y matar el proceso mismo.
EDIT5: Utilizando EDIT4, si hago una solicitud a cualquier punto final, obtengo una página de regreso, pero los errores de la botella se eliminan:
Bottle vx.x.x server starting up (using WSGIRefServer())...
Listening on <URL>
Hit Ctrl-C to quit.
----------------------------------------
Exception happened during processing of request from ('<IP>', 55104)
fuente
strace
si está utilizando Linux otruss
si está ejecutando Solaris y ver cómo / por qué termina. Como por ejemplossh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> strace -fo /tmp/debug ./startup.sh
.&
al final del script de inicio? Agregar el le&
quita la dependencia de su sesión ssh de ser la identificación principal (cuando los identificadores principales mueren, también lo hacen sus hijos). También creo que esta es una pregunta duplicada basada en esta publicación anterior. La publicación que le envié en la oración anterior es un duplicado de esta publicación que podría proporcionar mejores detalles.nohup ./startup.sh &
antes, pero tuvo el mismo comportamiento.startup.sh
ya contiene un tenedor (nohup python3 -u <script> &
), así que estoy bastante seguro de que no necesito bifurcar nuevamente.Respuestas:
Desconectaría el comando de su entrada / salida estándar y flujos de error:
ssh
necesita un indicador que no tenga más salida y que no requiera más entrada. Tener otra cosa que sea la entrada y redirigir los medios de salidassh
puede salir de forma segura, ya que la entrada / salida no viene ni va al terminal. Esto significa que la entrada debe provenir de otro lugar y la salida (tanto STDOUT como STDERR) debe ir a otro lugar.La
</dev/null
parte se especifica/dev/null
como entrada para<script>
. Por qué eso es útil aquí:Alternativamente, la redirección desde otra fuente de entrada debería ser relativamente segura siempre que
ssh
no sea necesario mantener abierta la sesión actual .Con el
>/dev/null
parte, el shell redirige la salida estándar a / dev / null esencialmente descartándola.>/path/to/file
También funcionará.La ultima parte
2>&1
es redirigir STDERR a STDOUT.fuente
nohup python3 -u <script> >/dev/null 2>&1 &
ynohup python3 -u <script> > nohup.out 2>&1 &
trabajado Sin embargo, pensé que nohup redirige automáticamente toda la salida: ¿cuál es la diferencia?nohup
tiene en su host remoto?nohup
No se requiere un POSIX para redirigirstdin
, lo cual me perdí, pero aún así debería redirigirstdout
ystderr
.nohup (GNU coreutils) 8.21
.nohup
imprimir los mensajes, comonohup: ignoring input and appending output to ‘nohup.out’
?Mira
man ssh
:Cuando corres
ssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> "./startup.sh"
, está ejecutando el script de shell startup.sh como un comando ssh.De la descripción:
En base a esto, debería ejecutar el script de forma remota.
La diferencia entre eso y correr
nohup python3 -u <script> &
en su terminal local es que esto se ejecuta como un proceso de fondo local mientras el comando ssh intenta ejecutarlo como un proceso de fondo remoto.Si tiene la intención de ejecutar el script localmente, no ejecute startup.sh como parte del comando ssh. Puedes intentar algo como
ssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> && "./startup.sh"
Si su intención es ejecutar el script de forma remota y desea que este proceso continúe después de que finalice su sesión ssh, primero deberá iniciar una
screen
sesión en el host remoto. Luego, debe ejecutar el script de Python dentro de la pantalla y continuará ejecutándose después de que finalice su sesión ssh.Consulte el Manual del usuario de la pantalla
Si bien creo que la pantalla es su mejor opción, si debe usar nohup, considere configurar
shopt -s huponexit
en el host remoto antes de ejecutar el comando nohup. Alternativamente, puede usardisown -h [jobID]
para marcar el proceso para que SIGHUP no se le envíe. 1Además, vea este resumen de cómo
huponexit
funciona cuando se sale de una concha, mató o se ha caído. Supongo que su problema actual está relacionado con cómo termina la sesión de shell. 2Por último, he aquí algunos ejemplos de cómo utilizar huponexit shopt. 3
fuente
bash
página del manual,huponexit
solo debería afectar a los shells interactivos y no a los scripts: "Si la opción de shell huponexit se ha configurado con shopt, bash envía un SIGHUP a todos los trabajos cuando sale un shell de inicio de sesión interactivo".Tal vez vale la pena probar la
-n
opción al comenzar unssh
? Se evitará la dependencia proceso remoto a nivel localstdin
, que por supuesto se cierra en cuantossh session
extremos. Y esto hará que los precios de terminación remotos cada vez que intenta acceder a sustdin
.fuente
Sospecho que tienes una condición de carrera. Sería algo parecido a esto:
Si ssh no hubiera acortado las cosas, habría sucedido lo siguiente (no estoy seguro sobre el orden de estos dos):
Así que los dos últimos pasos críticos no suceden, porque startup.sh y ssh meta antes nohup tiene tiempo para hacer su cosa.
Espero que su problema desaparezca si coloca unos segundos de suspensión al final de startup.sh. No estoy seguro de cuánto tiempo necesitas exactamente. Si es importante mantenerlo al mínimo, entonces tal vez pueda mirar algo en proceso para ver cuándo es seguro.
fuente
/proc/$!/comm
no esnohup
más portátilps -o comm= $!
.Esto suena más como un problema con lo que está haciendo el
python
script o enpython
sí mismo. Todo lo quenohup
realmente hace (barras que simplifican los redireccionamientos) es simplemente configurar el controlador para que laHUP
señalSIG_IGN
(ignorar) antes de ejecutar el programa. No hay nada que impida que el programa lo vuelva a configurarSIG_DFL
o que instale su propio controlador una vez que comience a ejecutarse.Una cosa que quizás desee probar es encerrar su comando entre paréntesis para que obtenga un efecto de doble tenedor y su
python
script ya no sea un elemento secundario del proceso de shell. P.ej:Otra cosa que también puede valer la pena intentar (si está usando
bash
y no otro shell) es usar eldisown
incorporado en lugar denohup
. Si todo funciona según lo documentado, esto no debería hacer ninguna diferencia, pero en un shell interactivo esto evitaría que laHUP
señal se propague a supython
script. Puede agregar el disown en la siguiente línea o la misma que se muestra a continuación (tenga en cuenta que agregar un;
after a&
es un errorbash
):Si lo anterior o alguna combinación no funciona, entonces seguramente el único lugar para abordar el problema es en el
python
script mismo.fuente
huponexit
cosas, ejecutarse en una subshell debería tener el mismo efecto yadisown
que el proceso no se agregará a la lista de trabajos.disown
. Sin embargo, no esperes que haga mucha diferencia. Creo que lo mejor es alterar elpython
guión para que te diga por qué está saliendo.nohup
hacerlo.Creo que es porque el trabajo está vinculado a la sesión. Una vez que finaliza, también se finalizan los trabajos de los usuarios.
fuente
Si
nohup
puede abrir su archivo de salida, puede tener una pistanohup.out
. Es posiblepython
que no esté en el camino cuando ejecuta el script víassh
.Intentaría crear un archivo de registro para el comando. Intenta usar:
fuente
ssh
para ejecutar el script manualmente, por lo que estoy asumiendo python3 está en el camino.