Fermeture de la connexion après l'exécution du redémarrage à l'aide de la commande ssh

18

J'utilise la reboot -fcommande à distance pour forcer le redémarrage d'une machine Unix. Le problème est que la connexion ssh reste active pendant longtemps, je ne sais pas pourquoi? Je veux fermer la connexion ssh immédiatement après le redémarrage de la machine et revenir à mon shell local. Comment puis je faire ça? Notez que la commande de redémarrage sans -findicateur ne fonctionne pas.

coffeMug
la source
1
Pourquoi ne pas simplement quitter votre connexion à distance (Ctrl + D) et laisser le serveur redémarrer sans que vous ayez à regarder l'invite du shell?
gertvdijk
Comment puis-je faire cela dans la même commande?
coffeMug
2
J'ai trouvé une solution pour cela qui pourrait également être utile pour d'autres. J'ai utilisé la commande suivante pour fermer la connexion juste après avoir démarré la commande associée à ssh: ssh host "commande à exécuter sur la machine hôte> / dev / null &" Je ne comprends pas bien la raison pour laquelle cette commande force la connexion à close done mais au moins ça m'a été utile. Si quelqu'un comprend la direction de la sortie de la commande vers / dev / null et pourquoi elle tue la connexion ssh, ce serait bien s'il / elle pouvait l'expliquer. :-)
coffeMug
ssh host "commande à exécuter sur la machine hôte> / dev / null &"
coffeMug
1
Ce n'est pas une réponse à cette question, mais il est utile de savoir quand même: Le client SSH a une série de caractères de contrôle qui peuvent être utilisés, entre autres, pour tuer le client. Les caractères de contrôle ne sont reconnus qu'immédiatement après une nouvelle ligne, commencez donc par appuyer sur Enter. Ensuite, par exemple ~.pour terminer la session. Enter ~?pour une liste des autres.
Tom

Réponses:

22

La commande reboot -fne revient jamais (sauf si vous n'avez pas été autorisé à provoquer un redémarrage). Au moment où il est émis, le client SSH attend quelque chose à faire, ce qui pourrait être:

  • le serveur SSH informant le client que quelque chose s'est produit qui requiert son attention, par exemple qu'il y a une sortie à afficher, ou que la commande à distance est terminée;
  • un événement côté client, comme un signal à relayer;
  • un minuteur se déclenchant pour amener le client à envoyer un message de maintien (et fermer la connexion si le serveur ne répond pas).

Étant donné que le processus du serveur SSH est mort, le client SSH ne mourra pas tant que la minuterie ne se déclenchera pas.

Si vous courez ssh remotehost 'reboot -f >/dev/null &', alors ce qui se passe est:

  1. Le shell distant lance la rebootcommande en arrière-plan.
  2. Étant donné que la commande shell côté serveur s'est terminée et qu'aucun processus ne maintient ouvert le descripteur de fichier pour la sortie standard, le serveur SSH ferme la connexion.
  3. La rebootcommande provoque le redémarrage de la machine.

Cependant, cela n'est pas fiable: selon le moment, l'étape 3 peut se produire avant l'étape 2. L'ajout d'un minuteur rend cela peu probable:

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

Pour être absolument sûr que le côté serveur est engagé dans l'exécution reboot, tout en s'assurant qu'il ne redémarre pas réellement avant d'aviser le client qu'il est validé, vous avez besoin d'une notification supplémentaire pour passer du serveur au client. Cela peut être émis via la connexion SSH, mais cela devient compliqué.

Gilles 'SO- arrête d'être méchant'
la source
2
Si quelqu'un cherche un moyen de le faire à partir de l'hôte distant (solution similaire): (sleep 1 && sudo reboot &) && exit . Les parenthèses génèrent un sous-processus, qui attend une seconde, puis lance le redémarrage. Cependant, le processus hôte met immédiatement fin à la session ssh. Je ne suis pas un gourou des coquillages, mais cela a fonctionné pour moi jusqu'à présent.
Griddo
@Griddo Cela a fonctionné fantastique et c'est un petit hack soigné. J'aime cela. Merci d'avoir partagé!
Joshua Pinter
5

J'ai trouvé cette solution pour faire le meilleur pour moi.

Utilisez -o "ServerAliveInterval 2"avec votre sshcommande, comme ceci:

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

Cette option oblige le côté client à pousser le serveur sur un canal sécurisé toutes les 2 secondes. Finalement, au fur et à mesure du redémarrage, il cessera de répondre et le client interrompra la connexion.

Roman Saveljev
la source
Merci Roman, ça marche comme par magie! :)
stdcerr
3

Certaines réponses étaient proches, mais la bonne réponse est:

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

explication:

  • vous souhaitez en exittant que dernière commande afin que le statut de la dernière commande soit 0 (succès). Vous pouvez ajouter un sommeil si vous le souhaitez, mais ce n'est pas nécessaire
  • vous devez exécuter le redémarrage en arrière-plan, car sinon le serveur fermera la connexion et vous obtiendrez une erreur. Il redémarrera toujours sur la plupart des systèmes, mais si vous créez un script, le statut de retour sera une erreur (pas 0), même si la commande s'exécute correctement.
  • en cours d' exécution sur l'arrière - plan ne suffit pas, comme stdinetstdout sont toujours connectés au terminal virtuel via SSH, de sorte que la connexion ne sera pas fermée. Vous devez faire deux choses supplémentaires pour que la session SSH se termine et laisser la commande s'exécuter en arrière-plan.
    • 1) vous devez rediriger stdoutet stderrvers /dev/nullafin qu'ils ne soient pas redirigés par le terminal virtuel qui détient la session SSH. C'est le&>/dev/null partie.
    • 2) vous devez rediriger stdinvers un fichier illisible de la même manière. C'est ce que fait le shell intégré nohup.

Avec seulement une commande exécutée en arrière-plan détachée du terminal dans tous les sens, exitfermera la session et parce qu'il n'y en a pas stdinou stdoutreste sur le terminal virtuel, SSH mettra fin à la connexion sans erreur.

nachoparker
la source
1

J'utilise la commande suivante:

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

Voici ce que cela fait:

  • Il demande à la machine de redémarrer au moment suivant, mais pas pendant cette commande
  • Quitte proprement SSH
  • Maintient le SSH TTY tout le temps afin que sudo soit heureux et puisse s'exécuter correctement.
stieg
la source
0

Avez-vous essayé ce qui suit

# shutdown -r now

Je trouve que sur certains systèmes sur lesquels j'ai travaillé dans la passe, la commande de redémarrage a eu quelques problèmes. Là encore, je ne trouve rien dans la page de manuel de shutdown qui ferait la même chose que le redémarrage avec l'indicateur -f.

Silverrocker
la source
1
Oui, l'arrêt ne fonctionne pas sur la machine à laquelle j'essaie de me connecter pour des raisons étranges. C'est pourquoi j'utilise reboot -f pour forcer un arrêt et redémarrer.
coffeMug
0

Que diriez-vous de quitter la session ssh et de redémarrer le système à l'aide de la commande suivante:

ssh login@host "reboot -f"

Après cela, appuyez simplement sur Ctrl + C pour terminer ssh.

Renat Zaripov
la source
0

J'ai trouvé une solution pour cela qui pourrait également être utile pour d'autres. J'ai utilisé la commande suivante pour fermer la connexion juste après avoir démarré la commande attachée à ssh:

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

Je ne comprends pas exactement la raison pour laquelle cette commande force la fermeture de la connexion mais au moins cela m'a été utile. Si quelqu'un comprend pourquoi il tue la connexion ssh; S'il vous plaît, expliquez.

coffeMug
la source
0

Cela nécessite un délai d'une minute mais a fonctionné de manière fiable pour moi et résout le problème du blocage du client SSH:

    $ sudo shutdown +1; logout

Cela planifie l'arrêt du système pendant 1 minute plus tard, ce qui laisse le temps à la déconnexion, et donc à la terminaison SSH, de se terminer. Si vous voulez attendre le moins de temps possible, vous pouvez remplacer le +1par HH:MMpour une heure de la journée qui approche rapidement, mais cela peut être difficile à chronométrer correctement et peut avoir jusqu'à 59 secondes de retard.

trpropst
la source
0

Un moyen simple que j'ai trouvé, est de commander l'arrêt / redémarrage en tant que tâche d'arrière-plan (en utilisant '&'), en le protégeant de la fermeture lorsque la session se ferme avec 'nohup', ainsi que la sortie immédiate du shell / session:

nohup shutdown -r now & exit

De cette façon, le client SSH ne se bloque pas, car la session se ferme immédiatement, tandis que le système distant procède à son redémarrage de manière asynchrone.

MikeW
la source
Ou substituez l'équivalent de votre système à "shutdown -r now" pour un redémarrage ....
MikeW
-2

Essayez cette commande:

$ reboot -f && exit
tH0r
la source
2
Malheureusement, cela ne fonctionne pas.
coffeMug
1
@AKh_Sw Soyez spécifique à "ne fonctionne pas".
gertvdijk
@AKh_Sw: si vous avez tapé le signe '$' cela ne fonctionnera pas
tH0r
1
Inutile. C'est exactement équivalent à reboot -f.
Gilles 'SO- arrête d'être méchant'