Tengo una máquina host que se reinicia o se vuelve a conectar varias veces. Quiero tener un script ejecutándose en mi máquina de desarrollo que continuamente intente iniciar sesión en esa máquina y, si tiene éxito, ejecuta un comando específico (siguiendo los datos de registro). Editar: para aclarar, la conexión debe permanecer abierta. El comando de registro sigue avanzando hasta que lo detengo manualmente.

Lo que tengo hasta ahora

#!/bin/bash

IP=192.168.178.1

if (("$#" >= 1))
then
  IP=$1
fi

LOOP=1

trap 'echo "stopping"; LOOP=0' INT

while (( $LOOP==1 ))
do
if ping -c1 $IP
then
  echo "Host $IP reached" 
  sshpass -p 'password' ssh -o ConnectTimeout=10 -q user@$IP '<command would go here>'
else
  echo "Host $IP unreachable"
fi
sleep 1

done

La bandera LOOP no se usa realmente. El guión finaliza mediante CTRL-C. Ahora, esto funciona si NO agrego un comando para que se ejecute después de ssh y en su lugar inicio la salida del registro manualmente. En una desconexión, el script sigue probando la conexión y vuelve a iniciar sesión una vez que el host está disponible nuevamente. Además, cuando me desconecto del host (CTRL-D), el script volverá a iniciar sesión en el host si CTRL-C no se presiona lo suficientemente rápido. Cuando agrego un comando para que se ejecute después de ssh, el bucle se rompe. Entonces, presionar (CTRL-C) no solo detiene el registro, sino que también desconecta y finaliza el script en la máquina de desarrollo.

¿Supongo que tengo que generar otro caparazón en alguna parte o algo así?

1) Quiero que el script siga probando, inicie sesión y ejecute un comando de forma completamente automática y vuelva a sondear cuando se interrumpa la conexión. 2) Quiero poder detener el registro en el host (CTRL-C) y, por lo tanto, recurrir a una conexión ssh iniciada para usarlo manualmente.

¿Cómo lo arreglo?

0
J-S 13 nov. 2017 a las 11:17

2 respuestas

La mejor respuesta

Quizás el mejor enfoque para "arreglar" sería fijar requisitos.

La parte problemática es la número "2)". El problema radica en cómo funciona SIGINT.

Cuando se activa, se envía al grupo de control actual relacionado con su terminal. En su mayoría, este es el shell y cualquier proceso que se inicie desde allí. Con shells más modernos (parece que usas bash), el shell administra los grupos de control de tal manera que los programas iniciados en segundo plano se desconectan (por haber sido asignados a un grupo de control diferente).

En su caso, ssh se inicia en primer plano (desde un script ejecutado en primer plano), por lo que recibirá la interrupción, la reenviará al control remoto y terminará tan pronto como termine el extremo remoto. Como en ese momento el script shell ha procesado su manejador de señales (especificado por trap) saldrá del bucle y terminará él mismo.

Entonces, como puede ver, ha sobrecargado CTRL-C para significar dos cosas:

  • terminar el script de monitoreo
  • terminar el comando remoto y continuar con lo que se especifique para el lado remoto.

Puede acercarse más a lo que desea si deja caer el primer efecto (o al menos lo hace más explícito). Luego, llamar a un script en el lado remoto que no se termina solo, sino solo el comando tail, será el paso. En ese caso, probablemente necesitará usar el interruptor -t en ssh para obtener una terminal asignada para permitir la operación de shell normal más adelante.

Esto no permitirá terminar el lado remoto con solo CTRL-C. Siempre necesitará salir del shell remoto que se ejecutará.

La esencia de un script remoto de este tipo podría verse así:

tail command
shell

Por supuesto, necesitará agregar las partes que sean necesarias para su shell o estilo de codificación.

Un enfoque alternativo sería mantener finalizado el comando remoto actual y agregar otra llamada ssh para el caso de ser interrumpido que se extiende por el shell para uso interactivo. Pero en ese caso, también `CTRL-C no estará disponible para terminar el menor por completo.

Para lograr esto, puede intentar cambiar el controlador de interrupciones activo con su script de monitoreo para activar la terminación tan pronto como regrese el lado remoto. Sin embargo, esto provocará una condición de carrera entre el usuario que puede reconocer el comando remoto terminado (y el control se ha devuelto a la secuencia de comandos local) y el controlador de interrupciones adecuado está en su lugar. Es posible que pueda reducir suficientemente ese riesgo activando primero el nuevo controlador trap y luego repitiendo el hecho y tal vez agregando un sueño para permitir que el usuario reaccione.

1
rpy 13 nov. 2017 a las 09:13

No estoy muy segura de lo que estás diciendo.

Además, debe desactivar PasswordAuthentication en / etc / ssh / sshd_config e iniciar sesión agregando la clave pública de su computadora personal a `~ / .ssh / allowed_keys

! / bin / sh

while [ true ];
do
    RESPONSE=`ssh -i /home/user/.ssh/id_host user@$IP 'tail /home/user/log.txt'`

    echo $RESPONSE

    sleep 10
done
0
Abdul Ahad 13 nov. 2017 a las 08:39