Đóng kết nối sau khi thực hiện khởi động lại bằng lệnh ssh


18

Tôi đang sử dụng reboot -flệnh từ xa để buộc khởi động lại máy Unix. Vấn đề là kết nối ssh vẫn hoạt động trong một thời gian dài mà tôi không biết tại sao? Tôi muốn đóng kết nối ssh ngay sau khi khởi động lại máy và trở về vỏ cục bộ. Làm thế nào tôi có thể làm điều đó? Lưu ý rằng lệnh khởi động lại không có -fcờ không hoạt động.


1
Tại sao không thoát khỏi kết nối từ xa của bạn (Ctrl + D) và để máy chủ khởi động lại mà không cần bạn phải xem dấu nhắc shell?
gertvdijk

Làm thế nào tôi có thể làm điều này trong cùng một lệnh?
coffeMug

2
Tôi tìm thấy một giải pháp cho việc này cũng có thể hữu ích cho những người khác. Tôi đã sử dụng lệnh sau để đóng kết nối ngay sau khi bắt đầu lệnh được gắn vào lệnh ssh: ssh host "để chạy trên máy chủ> / dev / null &" Tôi không hiểu lý do tại sao lệnh này buộc kết nối phải gần thực hiện nhưng ít nhất nó là hữu ích cho tôi. Nếu bất cứ ai hiểu chỉ đạo đầu ra của lệnh thành / dev / null và tại sao nó giết kết nối ssh thì sẽ rất tuyệt nếu anh ấy / cô ấy có thể giải thích nó. :-)
coffeMug

ssh host "lệnh chạy trên máy chủ> / dev / null &"
coffeMug

1
Đây không phải là câu trả lời cho câu hỏi này, nhưng dù sao cũng rất hữu ích: Máy khách SSH có một loạt các ký tự điều khiển có thể được sử dụng, trong số những thứ khác, để giết máy khách. Các ký tự điều khiển chỉ được nhận ra ngay sau một dòng mới, vì vậy hãy bắt đầu bằng cách nhấn Enter. Sau đó, ví dụ ~.để chấm dứt phiên. Enter ~?cho một danh sách những người khác.
Tom

Câu trả lời:


22

Lệnh reboot -fkhông bao giờ trả lại (trừ khi bạn không có quyền gây ra khởi động lại). Tại thời điểm phát hành, máy khách SSH đang chờ một cái gì đó để làm, đó có thể là:

  • máy chủ SSH thông báo cho khách hàng rằng có một cái gì đó đã xảy ra đòi hỏi sự chú ý của nó, ví dụ như có một số đầu ra để hiển thị hoặc lệnh từ xa đã kết thúc;
  • một số sự kiện ở phía khách hàng, chẳng hạn như tín hiệu chuyển tiếp;
  • một bộ đếm thời gian kích hoạt để khiến khách hàng gửi tin nhắn cố định (và đóng kết nối nếu máy chủ không trả lời).

Vì quá trình máy chủ SSH đã chết, máy khách SSH sẽ không chết cho đến khi bộ đếm thời gian kích hoạt.

Nếu bạn chạy ssh remotehost 'reboot -f >/dev/null &', thì những gì xảy ra là:

  1. Shell từ xa khởi chạy rebootlệnh trong nền.
  2. Vì lệnh shell phía máy chủ đã thoát và không có quá trình giữ bộ mô tả tệp cho đầu ra tiêu chuẩn mở, máy chủ SSH sẽ đóng kết nối.
  3. Các rebootlệnh gây ra máy để khởi động lại.

Tuy nhiên, điều này không đáng tin cậy: tùy thuộc vào thời gian, bước 3 có thể xảy ra trước bước 2. Thêm bộ hẹn giờ khiến điều này khó xảy ra:

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

Để chắc chắn rằng phía máy chủ cam kết chạy reboot, trong khi đảm bảo rằng nó không thực sự khởi động lại trước khi thông báo cho khách hàng rằng nó đã được cam kết, bạn cần một thông báo bổ sung để đi từ máy chủ đến máy khách. Đây có thể là đầu ra thông qua kết nối SSH, nhưng nó trở nên phức tạp.


2
Trong trường hợp bất cứ ai đang tìm kiếm một cách để làm điều này từ bên trong máy chủ từ xa (giải pháp tương tự) : (sleep 1 && sudo reboot &) && exit. Các dấu ngoặc đơn sinh ra một quy trình con, đợi một giây và sau đó bắt đầu khởi động lại. Quá trình lưu trữ tuy nhiên ngay lập tức chấm dứt phiên ssh. Tôi không phải là một bậc thầy về vỏ, nhưng điều này đã làm việc cho tôi cho đến nay.
Griddo

@Griddo Điều đó đã làm việc tuyệt vời và là một hack nhỏ gọn. Tôi thích nó. Cám ơn vì đã chia sẻ!
Joshua Pinter

5

Tôi tìm thấy giải pháp này để thực hiện tốt nhất cho tôi.

Sử dụng -o "ServerAliveInterval 2"với sshlệnh của bạn , như vậy:

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

Tùy chọn nói trên làm cho phía máy khách chọc máy chủ qua kênh an toàn cứ sau 2 giây. Cuối cùng, khi quá trình khởi động lại được tiến hành, nó sẽ dừng lại để phản hồi và máy khách sẽ phá hỏng kết nối.


Cảm ơn Roman, hoạt động như ma thuật! :)
stdcerr

3

Một số câu trả lời đã gần, nhưng câu trả lời đúng là:

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

giải trình:

  • bạn muốn exitlàm lệnh cuối cùng để trạng thái của lệnh cuối cùng là 0 (thành công). Bạn có thể chuẩn bị một giấc ngủ nếu bạn muốn, nhưng nó không cần thiết
  • bạn cần chạy khởi động lại trong nền, vì nếu không máy chủ sẽ đóng kết nối và bạn sẽ gặp lỗi. Nó vẫn sẽ khởi động lại trên hầu hết các hệ thống nhưng nếu bạn đang script thì trạng thái trả về sẽ là lỗi (không phải 0) ngay cả khi lệnh thực thi đúng
  • chạy trên nền là không đủ, vì stdinstdoutvẫn được gắn vào thiết bị đầu cuối ảo thông qua SSH, vì vậy kết nối sẽ không bị đóng. Bạn cần làm thêm hai điều nữa để phiên SSH kết thúc và để lệnh chạy trên nền.
    • 1) bạn cần chuyển hướng stdoutstderrđể /dev/nullchúng không bị chuyển hướng bởi thiết bị đầu cuối ảo chứa phiên SSH. Đây là &>/dev/nullmột phần.
    • 2) bạn cần chuyển hướng stdinđến một tệp không thể đọc được theo cùng một cách. Đó là những gì vỏ dựng sẵn nohuplàm.

Chỉ với một lệnh chạy trên nền được nhúng từ thiết bị đầu cuối theo mọi cách, exitsẽ đóng phiên và vì không có stdinhoặc stdoutcòn lại trên thiết bị đầu cuối ảo, SSH sẽ chấm dứt kết nối mà không gặp lỗi.


1

Tôi sử dụng lệnh sau:

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

Đây là những gì nó đang làm:

  • Nó ra lệnh cho máy khởi động lại trong khoảnh khắc tiếp theo, nhưng không phải trong lệnh này
  • Thoát khỏi sạch khỏi SSH
  • Duy trì SSH TTY toàn bộ thời gian để sudo hạnh phúc và có thể thực thi đúng cách.

0

Bạn đã thử như sau chưa?

# shutdown -r now

Tôi thấy rằng trên một số hệ thống tôi đã làm việc trong pass, lệnh khởi động lại có một số vấn đề. Sau đó, một lần nữa tôi không thể tìm thấy bất cứ điều gì trong trang web tắt máy sẽ làm tương tự như khởi động lại với cờ -f.


1
Có, tắt máy không hoạt động trong máy mà tôi đang cố gắng kết nối vì một số lý do lạ. Đó là lý do tại sao tôi sử dụng khởi động lại -f để buộc tắt máy và khởi động lại.
coffeMug

0

Cách thoát khỏi phiên ssh và hệ thống khởi động lại bằng lệnh tiếp theo:

ssh login@host "reboot -f"

Sau đó, chỉ cần nhấn Ctrl + C để kết thúc ssh.


0

Tôi tìm thấy một giải pháp cho việc này cũng có thể hữu ích cho những người khác. Tôi đã sử dụng lệnh sau để đóng kết nối ngay sau khi bắt đầu lệnh được gắn vào ssh:

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

Tôi không hiểu chính xác lý do tại sao lệnh này buộc kết nối phải đóng nhưng ít nhất nó cũng hữu ích cho tôi. Nếu bất cứ ai hiểu tại sao nó giết kết nối ssh; vui lòng giải thích.


0

Điều này đòi hỏi độ trễ 1 phút nhưng đã hoạt động đáng tin cậy đối với tôi và giải quyết vấn đề treo máy khách SSH:

    $ sudo shutdown +1; logout

Việc này lên lịch tắt hệ thống trong 1 phút sau đó cho phép thời gian đăng xuất và do đó chấm dứt SSH, hoàn tất. Nếu bạn muốn đợi càng ít thời gian càng tốt, bạn có thể thay thế +1bằng HH:MMthời gian tiếp cận nhanh trong ngày nhưng điều đó có thể khó khăn về thời gian một cách chính xác và có thể có độ trễ lên tới 59 giây.


0

Một cách đơn giản mà tôi đã tìm thấy, là ra lệnh tắt / khởi động lại làm tác vụ nền (sử dụng '&'), bảo vệ nó khỏi bị đóng khi phiên đóng với 'nohup', cùng với thoát khỏi shell / phiên ngay lập tức:

nohup shutdown -r now & exit

Theo cách này, máy khách SSH không bị treo, vì phiên thoát ngay lập tức, trong khi hệ thống từ xa tiến hành khởi động lại không đồng bộ.


Hoặc thay thế hệ thống của bạn tương đương với "shutdown -r now" để khởi động lại ....
MikeW

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.