Cerrar la conexión después de ejecutar el reinicio con el comando ssh

18

Estoy usando el reboot -fcomando de forma remota para forzar el reinicio de una máquina Unix. El problema es que la conexión ssh permanece activa durante mucho tiempo y no sé por qué. Quiero cerrar la conexión ssh inmediatamente después de reiniciar la máquina y volver a mi shell local. ¿Cómo puedo hacer eso? Tenga en cuenta que el comando de reinicio sin -fbandera no funciona.

taza de cafe
fuente
1
¿Por qué no simplemente salir de su conexión remota (Ctrl + D) y dejar que el servidor se reinicie sin que tenga que mirar el indicador de comandos de shell?
gertvdijk
¿Cómo puedo hacer esto en el mismo comando?
coffeMug
2
Encontré una solución para esto que podría ser útil para otros también. Usé el siguiente comando para cerrar la conexión justo después de iniciar el comando adjunto a ssh: ssh host "comando para ejecutar en la máquina host> / dev / null &" No entiendo completamente la razón por la cual este comando fuerza la conexión a hecho, pero al menos fue útil para mí. Si alguien entiende la dirección de la salida del comando a / dev / null y por qué mata la conexión ssh, sería bueno si él / ella puede explicarlo. :-)
coffeMug
ssh host "comando para ejecutar en la máquina host> / dev / null &"
coffeMug
1
No es una respuesta a esta pregunta, pero es útil saber de todos modos: el cliente SSH tiene una serie de caracteres de control que se pueden usar, entre otras cosas, para matar al cliente. Los caracteres de control solo se reconocen inmediatamente después de una nueva línea, así que comience presionando Enter. Entonces, por ejemplo, ~.para finalizar la sesión. Enter ~?para una lista de otros.
Tom

Respuestas:

22

El comando reboot -fnunca regresa (a menos que no tenga permiso para provocar un reinicio). En el punto donde se emite, el cliente SSH está esperando algo que hacer, que podría ser:

  • el servidor SSH notifica al cliente que sucedió algo que requiere su atención, por ejemplo, que hay algo que mostrar o que el comando remoto ha finalizado;
  • algún evento en el lado del cliente, como una señal para retransmitir;
  • un temporizador que se activa para que el cliente envíe un mensaje de alerta (y cierre la conexión si el servidor no responde).

Dado que el proceso del servidor SSH está inactivo, el cliente SSH no morirá hasta que se active el temporizador.

Si corres ssh remotehost 'reboot -f >/dev/null &', entonces lo que sucede es:

  1. El shell remoto inicia el rebootcomando en segundo plano.
  2. Debido a que el comando de shell del lado del servidor ha salido y no hay ningún proceso que mantenga abierto el descriptor de archivo para la salida estándar, el servidor SSH cierra la conexión.
  3. El rebootcomando hace que la máquina se reinicie.

Sin embargo, esto no es confiable: dependiendo del tiempo, el paso 3 podría ocurrir antes del paso 2. Agregar un temporizador hace que esto sea poco probable:

ssh remotehost '{ sleep 1; reboot -f; } >/dev/null &'

Para estar absolutamente seguro de que el lado del servidor está comprometido a ejecutarse reboot, mientras se asegura de que en realidad no se reinicie antes de notificar al cliente que está comprometido, necesita una notificación adicional para ir del servidor al cliente. Esto se puede generar a través de la conexión SSH, pero se complica.

Gilles 'SO- deja de ser malvado'
fuente
2
En caso de que alguien está buscando una manera de hacer esto desde dentro del host remoto (solución similar): (sleep 1 && sudo reboot &) && exit. Los paréntesis generan un subproceso, que espera un segundo y luego inicia el reinicio. Sin embargo, el proceso de host finaliza inmediatamente la sesión ssh. No soy un gurú de la concha, pero esto funcionó para mí hasta ahora.
Griddo
@Griddo Eso funcionó de maravilla y es un pequeño truco. Me encanta. ¡Gracias por compartir!
Joshua Pinter el
5

Encontré esta solución para dar lo mejor de mí.

Úselo -o "ServerAliveInterval 2"con su sshcomando, así:

$ ssh -o "ServerAliveInterval 2" root@remotehost reboot

Dicha opción hace que el lado del cliente empuje el servidor sobre un canal seguro cada 2 segundos. Finalmente, a medida que avanza el reinicio, se detendrá para responder y el cliente cortará la conexión.

Roman Saveljev
fuente
Gracias Roman, funciona como magia! :)
stdcerr
3

Algunas respuestas fueron cercanas, pero la respuesta correcta es:

ssh [email protected] "nohup sudo reboot &>/dev/null & exit"

explicación:

  • desea que exitsea ​​el último comando, por lo que el estado del último comando es 0 (correcto). Puede pretender dormir si lo desea, pero no es necesario
  • necesita reiniciar en segundo plano, porque de lo contrario el servidor cerrará la conexión y obtendrá un error. Todavía se reiniciará en la mayoría de los sistemas, pero si está generando scripts, el estado de retorno será un error (no 0) incluso con el comando ejecutándose correctamente
  • que se ejecuta en el fondo no es suficiente, ya que el stdiny stdouttodavía están unidos a la terminal virtual a través de SSH, por lo que no se cerrará la conexión. Debe hacer dos cosas adicionales para que finalice la sesión SSH y dejar el comando ejecutándose en segundo plano.
    • 1) necesita redirigir stdouty stderrpara /dev/nullque no sean redirigidos por el terminal virtual que contiene la sesión SSH. Esta es la &>/dev/nullparte
    • 2) necesita redirigir stdina un archivo ilegible de la misma manera. Eso es lo que hace el shell incorporado nohup.

Con solo un comando ejecutándose en segundo plano, desconectado de la terminal en todos los sentidos, exitcerrará la sesión y, dado que no hay ninguna stdino stdoutqueda en la terminal virtual, SSH terminará la conexión sin errores.

nachoparker
fuente
1

Yo uso el siguiente comando:

ssh -t <hostname> 'sudo shutdown --reboot 0 && exit'

Esto es lo que está haciendo esto:

  • Le indica a la máquina que se reinicie en el momento siguiente, pero no durante este comando
  • Sale limpiamente de SSH
  • Mantiene el SSH TTY todo el tiempo para que sudo esté contento y pueda ejecutarse correctamente.
stieg
fuente
0

Has intentado lo siguiente

# shutdown -r now

Me parece que en algunos sistemas en los que trabajé en el pase, el comando de reinicio tuvo algunos problemas. Por otra parte, no puedo encontrar nada en la página de manual de apagado que haría lo mismo que reiniciar con la bandera -f.

Silverrocker
fuente
1
Sí, el apagado no funciona en la máquina a la que intento conectarme por algunas razones extrañas. Es por eso que uso reiniciar -f para forzar un apagado y reiniciar.
coffeMug
0

¿Qué tal salir de la sesión ssh y reiniciar el sistema usando el siguiente comando:

ssh login@host "reboot -f"

Después de esto, simplemente presione Ctrl + C para terminar ssh.

Renat Zaripov
fuente
0

Encontré una solución para esto que podría ser útil para otros también. Usé el siguiente comando para cerrar la conexión justo después de iniciar el comando adjunto a ssh:

ssh host "command to run on the host machine > /dev/null &"

No entiendo exactamente la razón por la cual este comando obliga a cerrar la conexión, pero al menos fue útil para mí. Si alguien entiende por qué mata la conexión ssh; por favor explique.

taza de cafe
fuente
0

Esto requiere un retraso de 1 minuto, pero ha funcionado de manera confiable para mí y resuelve el problema del bloqueo del cliente SSH:

    $ sudo shutdown +1; logout

Esto programa el apagado del sistema para 1 minuto más tarde, lo que permite que finalice el cierre de sesión y, por lo tanto, la finalización de SSH. Si desea esperar el menor tiempo posible, se podría reemplazar el +1con HH:MMun tiempo que se acercaba rápidamente del día, pero que puede ser difícil de tiempo correctamente y puede tener hasta 59 segundos de retraso.

trpropst
fuente
0

Una manera simple que he encontrado es ordenar el apagado / reinicio como una tarea en segundo plano (usando '&'), protegiéndolo de que se cierre cuando la sesión se cierra con 'nohup', junto con la salida inmediata de shell / sesión:

nohup shutdown -r now & exit

De esta forma, el cliente SSH no se bloquea, ya que la sesión se cierra de inmediato, mientras que el sistema remoto continúa con el reinicio de forma asincrónica.

MikeW
fuente
O sustituir el sistema de equivalente a "shutdown -r now" para reiniciar ....
MikeW
-2

Prueba este comando:

$ reboot -f && exit
tH0r
fuente
2
Lamentablemente esto no funciona.
coffeMug
1
@AKh_Sw Sea específico para "no funciona".
gertvdijk
@AKh_Sw: si escribiste el signo '$' no funcionará
tH0r
1
Inútil. Esto es exactamente equivalente a reboot -f.
Gilles 'SO- deja de ser malvado'