Закрытие соединения после выполнения перезагрузки с помощью команды ssh

18

Я использую reboot -fкоманду удаленно, чтобы принудительно перезагрузить компьютер Unix. Проблема в том, что ssh-соединение остается активным долгое время, чего я не знаю почему? Я хочу закрыть ssh-соединение сразу после перезагрузки компьютера и вернуться в локальную оболочку. Как я могу это сделать? Обратите внимание, что команда перезагрузки без -fфлага не работает.

coffeMug
источник
1
Почему бы просто не выйти из удаленного соединения (Ctrl + D) и позволить перезагрузить сервер, не наблюдая за приглашением оболочки?
gertvdijk
Как я могу сделать это в той же команде?
coffeMug 12.12.12
2
Я нашел решение для этого, которое может быть полезным и для других. Я использовал следующую команду, чтобы закрыть соединение сразу после запуска команды, прикрепленной к ssh: ssh host "команда для запуска на хост-компьютере> / dev / null &" Я не до конца понимаю причину, по которой эта команда вызывает соединение близко сделано, но по крайней мере это было полезно для меня. Если кто-то понимает направление вывода команды в / dev / null и почему он убивает ssh-соединение, было бы неплохо, если бы он мог объяснить это. :-)
coffeMug
ssh host "команда для запуска на хост-компьютере> / dev / null &"
coffeMug
1
Это не ответ на этот вопрос, но полезно знать в любом случае: SSH-клиент имеет ряд управляющих символов, которые можно использовать, среди прочего, для уничтожения клиента. Управляющие символы распознаются только сразу после новой строки, поэтому начинайте с нажатия Enter. Затем, например, ~.чтобы прекратить сеанс. Enter ~?для списка других.
Том

Ответы:

22

Команда reboot -fникогда не возвращается (если только у вас не было разрешения на перезагрузку). В момент его выдачи SSH-клиент ожидает выполнения каких-либо действий:

  • SSH-сервер уведомляет клиента о том, что произошло что-то, что требует его внимания, например, о том, что есть какие-то выходные данные для отображения, или что удаленная команда завершила работу;
  • какое-то событие на стороне клиента, например сигнал для ретрансляции;
  • таймер запускается, чтобы заставить клиента отправить сообщение keepalive (и закрыть соединение, если сервер не отвечает).

Поскольку процесс сервера SSH не работает, клиент SSH не умрет, пока не сработает таймер.

Если вы запустите ssh remotehost 'reboot -f >/dev/null &', то что произойдет:

  1. Удаленная оболочка запускает rebootкоманду в фоновом режиме.
  2. Поскольку команда оболочки на сервере завершилась, и нет никакого процесса, удерживающего дескриптор файла для стандартного открытия вывода, SSH-сервер закрывает соединение.
  3. Команда rebootвызывает перезагрузку машины.

Однако это ненадежно: в зависимости от времени, шаг 3 может произойти до шага 2. Добавление таймера делает это маловероятным:

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

Чтобы быть абсолютно уверенным в том, что сторона сервера настроена на работу reboot, при этом убедитесь, что она фактически не перезагружается, прежде чем уведомлять клиента о том, что она зафиксирована, вам нужно дополнительное уведомление для перехода с сервера на клиент. Это может быть выведено через соединение SSH, но это становится сложным.

Жиль "ТАК - прекрати быть злым"
источник
2
В случае , если кто - то ищет способ сделать это изнутри удаленного хоста (аналогичный раствор): (sleep 1 && sudo reboot &) && exit. Скобки порождают подпроцесс, который ждет одну секунду, а затем инициирует перезагрузку. Однако хост-процесс немедленно завершает сеанс ssh. Я не гуру из снарядов, но до сих пор это работало для меня.
Griddo
@Griddo Это сработало просто фантастически, и это был небольшой хитрость. Я люблю это. Спасибо, что поделился!
Джошуа Пинтер
5

Я нашел это решение, чтобы выполнить лучшее для меня.

Используйте -o "ServerAliveInterval 2"с вашей sshкомандой, вот так:

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

Указанная опция заставляет клиентскую сторону каждые 2 секунды проталкивать сервер по безопасному каналу. В конце концов, когда перезагрузка продолжается, он перестает отвечать, и клиент разрывает соединение.

Роман Савельев
источник
Спасибо Роман, работает как по волшебству! :)
stdcerr
3

Некоторые ответы были близки, но правильный ответ:

ssh user@192.168.0.130 "nohup sudo reboot &>/dev/null & exit"

объяснение:

  • Вы хотите, чтобы exitв качестве последней команды, поэтому статус последней команды 0 (успех). Вы можете приготовить сон, если хотите, но это не обязательно.
  • вам нужно запустить перезагрузку в фоновом режиме, потому что в противном случае сервер закроет соединение, и вы получите ошибку. Он все еще будет перезагружаться на большинстве систем, но если вы пишете сценарий, возвращаемым статусом будет ошибка (не 0) даже при правильном выполнении команды
  • работающие на заднем плане не хватает, как stdinи stdoutвсе еще привязаны к виртуальному терминалу через SSH, поэтому соединение не будет закрыто. Чтобы завершить сеанс SSH, нужно сделать две дополнительные вещи и оставить команду работающей в фоновом режиме.
    • 1) Вы должны перенаправить stdoutи stderrна /dev/nullтак они не перенаправляются виртуальный терминал , который содержит SSH сессии. Это &>/dev/nullчасть.
    • 2) вам нужно перенаправить stdinна нечитаемый файл тем же способом. Это то, что nohupделает встроенная оболочка .

Если только команда, работающая в фоновом режиме и всячески отсоединенная от терминала, exitзакроет сеанс, а поскольку на виртуальном терминале его нет stdinили он stdoutостанется, SSH прервет соединение без ошибок.

nachoparker
источник
1

Я использую следующую команду:

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

Вот что это делает:

  • Он дает команду машине перезагрузиться в следующий момент, но не во время этой команды
  • Чисто выходит из SSH
  • Поддерживает SSH TTY все время, поэтому sudo доволен и может работать должным образом.
Стиг
источник
0

Вы пробовали следующее

# shutdown -r now

Я обнаружил, что в некоторых системах, над которыми я работал на проходе, у команды перезагрузки были некоторые проблемы. С другой стороны, я не могу найти ничего в справочной странице shutdown, которая бы делала то же самое, что и перезагрузка с флагом -f.

Silverrocker
источник
1
Да, выключение не работает в машине, к которой я пытаюсь подключиться по каким-то странным причинам. Вот почему я использую перезагрузку -f для принудительного завершения работы и перезагрузки.
coffeMug
0

Как насчет выхода из сеанса ssh и перезагрузки системы с помощью следующей команды:

ssh login@host "reboot -f"

После этого просто нажмите Ctrl + C для завершения SSH.

Ренат Зарипов
источник
0

Я нашел решение для этого, которое может быть полезным и для других. Я использовал следующую команду, чтобы закрыть соединение сразу после запуска команды, прикрепленной к ssh:

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

Я не совсем понимаю причину, по которой эта команда принудительно закрывает соединение, но, по крайней мере, она мне помогла. Если кто-то понимает, почему он убивает соединение ssh; пожалуйста, объясни.

coffeMug
источник
0

Это требует 1-минутной задержки, но сработало для меня надежно и решает проблему зависания клиента SSH:

    $ sudo shutdown +1; logout

Это планирует отключение системы на 1 минуту позже, что дает время для завершения выхода из системы и, следовательно, завершения SSH. Если вы хотите , чтобы ждать , как мало времени , как это возможно, вы могли бы заменить +1с HH:MMдля быстро приближающегося времени суток , но это может быть сложно времени правильно и может иметь до второй задержки 59.

trpropst
источник
0

Простой способ, который я нашел, - это выполнить команду shutdown / reboot в качестве фоновой задачи (используя '&'), защищая ее от закрытия при закрытии сеанса с помощью nohup вместе с немедленным завершением оболочки / сессии:

nohup shutdown -r now & exit

Таким образом, клиент SSH не зависает, так как сеанс завершается немедленно, а удаленная система выполняет свою перезагрузку асинхронно.

MikeW
источник
Или замените эквивалент вашей системы на «shutdown -r now» для перезагрузки…
MikeW
-2

Попробуйте эту команду:

$ reboot -f && exit
Th0R
источник
2
К сожалению, это не работает.
coffeMug 12.12.12
1
@AKh_Sw Будьте конкретны с "не работает".
gertvdijk
@AKh_Sw: если вы ввели знак «$», он не будет работать
tH0r
1
Бесполезный. Это в точности эквивалентно reboot -f.
Жиль "ТАК - перестань быть злым"