23

I am using the reboot -f command remotely to force reboot a Unix machine. The problem is that the ssh connection remains active for a long time which I don't know why? I want to close the ssh connection immediately after rebooting the machine and return to my local shell. How can i do that? Note that the reboot command without -f flag does not work.

6
  • 1
    Why not just exit your remote connection (Ctrl+D) and let the server reboot without you having to watch the shell prompt?
    – gertvdijk
    Commented Dec 12, 2012 at 9:35
  • How can i do this in the same command?
    – Vombat
    Commented Dec 12, 2012 at 10:23
  • 2
    I found a solution for this which might be helpful for others as well. I used the following command to close the connection right after starting the command attached to ssh: ssh host "command to run on the host machine > /dev/null &" I don't fully understand the reason why this command forces the connection to close done but at least it was helpful for me. If anyone understands the directing of the output of the command to /dev/null and why it kills the ssh connection it would be nice if he/she can explain it. :-)
    – Vombat
    Commented Dec 12, 2012 at 13:14
  • ssh host "command to run on the host machine > /dev/null &"
    – Vombat
    Commented Dec 12, 2012 at 13:15
  • 1
    It's not an answer to this question, but it's useful to know anyway: The SSH client has a series of control characters that can be used, among other things, to kill the client. Control characters are only recognized immediately after a newline, so start by pressing Enter. Then eg ~. to terminate the session. Enter ~? for a list of others.
    – Tom
    Commented Oct 19, 2018 at 13:39

10 Answers 10

24

The command reboot -f never returns (unless you didn't have permission to cause a reboot). At the point where it is issued, the SSH client is waiting for something to do, which could be:

  • the SSH server notifying the client that something happened that requires its attention, for example that there is some output to display, or that the remote command has finished;
  • some event on the client side, such as a signal to relay;
  • a timer firing up to cause the client to send a keepalive message (and close the connection if the server doesn't reply).

Since the SSH server process is dead, the SSH client won't die until the timer fires up.

If you run ssh remotehost 'reboot -f >/dev/null &', then what happens is:

  1. The remote shell launches the reboot command in the background.
  2. Because the server-side shell command has exited and there is no process holding the file descriptor for standard output open, the SSH server closes the connection.
  3. The reboot command causes the machine to reboot.

However, this is not reliable: depending on timing, step 3 might happen before step 2. Adding a timer makes this unlikely:

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

To be absolutely sure that the server side is committed to running reboot, while making sure that it doesn't actually reboot before notifying the client that it is committed, you need an additional notification to go from the server to the client. This can be output through the SSH connection, but it gets complicated.

2
  • 6
    In case anyone is looking for a way to do this from within the remote host (similar solution): (sleep 1 && sudo reboot &) && exit. The parentheses spawn a subprocess, which waits one second and then initiates the reboot. The host process however immediately terminates the ssh session. I'm not a shell guru, but this worked for me so far.
    – Gerrit-K
    Commented Dec 12, 2016 at 20:16
  • @Griddo That worked fantastic and is a neat little hack. I love it. Thanks for sharing! Commented Nov 28, 2018 at 18:35
13

I found this solution to perform the best for me.

Use -o "ServerAliveInterval 2" with your ssh command, like so:

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

The said option makes the client side poke the server over a secure channel every 2 seconds. Eventually as the rebooting proceeds, it will stop to respond and the client will tear the connection down.

2
  • Thanks Roman, works like magic! :)
    – stdcerr
    Commented Jul 31, 2019 at 15:04
  • Can you have two -o flag in a single call? I need to also run -o StrictHostKeyChecking=no Commented Apr 22, 2020 at 16:48
13

Some answers were close, but the right answer is:

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

explanation:

  • you want to exit as the last command so the status of the last command is 0 (success). You can prepend a sleep if you wish, but it is not necessary
  • you need to run reboot in the background, because otherwise the server will close the connection and you will get an error. It will still reboot on most systems but if you are scripting the return status will be error (not 0) even with the command executing properly
  • running on the background is not enough, as the stdin and stdout are still attached to the virtual terminal through SSH, so the connection will not be closed. You need to do two extra things for the SSH session to end and leave the command running on the background.
    • 1) you need to redirect stdout and stderr to /dev/null so they are not redirected by the virtual terminal that holds the SSH session. This is the &>/dev/null part.
    • 2) you need to redirect stdin to an unreadable file in the same fashion. That is what the shell builtin nohup does.

With only a command running on the background dettached from the terminal in every way, exit will close the session and because there are no stdin or stdout left on the virtual terminal SSH will terminate the connection without errors.

1
  • I am writing BATS test automation script and this answer, with explanation on how to properly reboot remote server without errors coming back, is just what I was looking for. Thank you. Commented Jul 24, 2022 at 4:11
3

I use the following command:

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

Here is what this is doing:

  • It instructs the machine to reboot in the next moment, but not during this command
  • Exits cleanly from SSH
  • Maintains the SSH TTY the entire time so sudo is happy and can execute properly.
0
0

Have you tried the following

# shutdown -r now

I find that on some systems I worked on in the pass, the reboot command had some problems. Then again I can't find anything in the manpage of shutdown that would do the same as reboot with the -f flag.

1
  • 1
    Yes, shutdown doesnot work in the machine which i am trying to connect to for some strange reasons. That is why i use reboot -f to force a shutdown and restart.
    – Vombat
    Commented Dec 12, 2012 at 13:08
0

I found a solution for this which might be helpful for others as well. I used the following command to close the connection right after starting the command attached to ssh:

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

I don’t exactly understand the reason why this command forces the connection to close but at least it was helpful for me. If anyone understands why it kills the ssh connection; please explain.

0

This requires a 1 minute delay but has worked reliably for me and solves the problem of the SSH client hang:

    $ sudo shutdown +1; logout

This schedules the system shutdown for 1 minute later which allows time for the logout, and hence SSH termination, to complete. If you want to wait as little time as possible, you could replace the +1 with HH:MM for a rapidly approaching time of day but that may be tricky to time correctly and may have up to a 59 second delay.

0

A simple way that I have found, is to command the shutdown/reboot as a background task (using '&'), protecting it from being closed when the session closes with 'nohup' , together with immediate shell/session exit:

nohup shutdown -r now & exit

In this way, the SSH client does not hang, since the session exits immediately, while the remote system proceeds with its reboot asynchronously.

1
  • Or substitute your system's equivalent to "shutdown -r now" for a reboot ....
    – MikeW
    Commented May 9, 2017 at 11:02
-1

How about exit from ssh session and reboot system using next command:

ssh login@host "reboot -f"

After this just press Ctrl+C for terminate ssh.

-3

Try this command:

$ reboot -f && exit
4
  • 2
    Unfortunately this doesn't work.
    – Vombat
    Commented Dec 12, 2012 at 10:27
  • 1
    @AKh_Sw Be specific to "doesn't work".
    – gertvdijk
    Commented Dec 12, 2012 at 12:44
  • @AKh_Sw : if you typed the '$' sign it won't work
    – tH0r
    Commented Dec 12, 2012 at 13:09
  • 1
    Useless. This is exactly equivalent to reboot -f. Commented Dec 12, 2012 at 23:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .