
Estoy intentando automatizar varias tareas comunes que realizo mediante SSH en un servidor remoto. Para esto, estoy usando PuTTY y su opción "comando remoto" (Conexión > SSH) en varias sesiones guardadas. Mi comando remoto se parece a esto:
~/scripts/test; $SHELL -l
El script ejecutado difiere según la sesión guardada y realiza diferentes tareas. $SHELL -l
mantiene activa la sesión de PuTTY después de que el script termina de ejecutarse.
Todo esto funciona perfectamente para la mayoría de los scripts que estoy ejecutando. Sin embargo, tengo uno que usa un bucle while para ejecutar una serie de comandos hasta que termina con Ctrl+C. El script comienza bien, pero el shell PuTTY no permanece activo una vez finalizado. $SHELL -l
no parece estar siendo ejecutado.
Un script de ejemplo con este comportamiento es el siguiente:
while true; do
echo "."
sleep 2
done
Lo siguiente funciona bien ejecutado manualmente, veo el resultado esperado del segundo comando:
~/scripts/test; echo "done"
Sin embargo, el segundo comando del "comando remoto" de PuTTY no se ejecuta. De hecho, si cambio el comando remoto para incluir un echo
, no se muestra.
~/scripts/test; echo "done"; $SHELL -l
Entonces, supongo que mi pregunta es: ¿por qué el segundo comando de la lista no se ejecuta mediante el comando remoto, mientras que sí lo hace cuando se ejecuta manualmente? Y, más importante aún, ¿qué puedo hacer al respecto?
Si es relevante, estoy ejecutando PuTTY en Ubuntu 14.04.
Respuesta1
Cuando ejecutas putty
o ssh
(no creo que haya ninguna diferencia en este contexto) con un comando para ejecutar en el sistema remoto, el servidor ssh remoto ejecuta el comando como un comando de shell:
/bin/bash -c '~/scripts/test; $SHELL -l'
Entonces tiene una bash
instancia en el sistema remoto que ejecuta esta canalización. También tiene otra bash
instancia, iniciada por la primera instancia, que ejecuta este script de "prueba".
Cuando escribe Control-C, putty
envía el carácter al sistema remoto donde su TTY lo interpreta como el carácter de interrupción. Esto da como resultado el envío de un SIGINT (señal de interrupción) a los procesos que están conectados al TTY. Esto interrumpe ambos procesos de Shell, provocando que ambos salgan. Quiere que la instancia de shell principal ignore SIGINT.
El comando bash para ignorar SIGINT es:
trap "" INT
Entonces, para deshabilitar SIGINT para su canalización, cambiaría su comando original a:
trap '' INT; ~/scripts/test; $SHELL -l
Pero esto también deshabilita SIGINT para procesos secundarios, lo que haría que el script de "prueba" fuera inmune a Ctrl-C. Por lo tanto, debe volver a habilitar SIGINT para el script de prueba. El comando para eso es:
trap INT
Puede agregar esa línea al script de prueba o puede agregarla a la canalización:
trap '' INT; ( trap INT; ~/scripts/test ); $SHELL -l
Ahora, cuando presiona Ctrl-C, debe interrumpir el proceso de "prueba", pero no el proceso principal que está ejecutando la canalización de comandos.
Puedes probar esto sin usar PuTTY o SSH. Simplemente ejecute estos comandos e intente presionar Ctrl-C mientras se ejecuta el "suspensión":
bash -c 'sleep 15; echo foo' # Ctrl-C kills sleep; doesn't print "foo"
bash -c 'trap "" INT ; sleep 15; echo foo' # Ctrl-C has no effect
bash -c 'trap "" INT; ( trap INT; sleep 15 ); echo foo' # Kills sleep, prints "foo"
Respuesta2
Ctrl+c para el comando remoto de PuTTY en realidad está interrumpiendo la sesión ssh, por lo que se debe esperar que no ejecute los comandos remotos restantes. Si su objetivo es simplemente que la sesión continúe activa, su bucle infinito debería ser suficiente.