การปิดการเชื่อมต่อหลังจากดำเนินการรีบูตโดยใช้คำสั่ง ssh


18

ฉันใช้reboot -fคำสั่งจากระยะไกลเพื่อบังคับให้รีบูตเครื่อง Unix ปัญหาคือการเชื่อมต่อ ssh ยังคงทำงานอยู่เป็นเวลานานซึ่งฉันไม่รู้ว่าทำไม? ฉันต้องการปิดการเชื่อมต่อ ssh ทันทีหลังจากรีบูตเครื่องและกลับสู่เชลล์ภายในเครื่องของฉัน ฉันจะทำสิ่งนั้นได้อย่างไร โปรดทราบว่าคำสั่ง reboot ที่ไม่มี-fแฟล็กไม่ทำงาน


1
ทำไมไม่เพียงออกจากการเชื่อมต่อระยะไกลของคุณ (Ctrl + D) และปล่อยให้เซิร์ฟเวอร์รีบูตโดยที่คุณไม่ต้องดูเชลล์พร้อมท์?
gertvdijk

ฉันจะทำสิ่งนี้ในคำสั่งเดียวกันได้อย่างไร
coffeMug

2
ฉันพบวิธีแก้ปัญหาสำหรับสิ่งนี้ซึ่งอาจเป็นประโยชน์สำหรับผู้อื่นเช่นกัน ฉันใช้คำสั่งต่อไปนี้เพื่อปิดการเชื่อมต่อทันทีหลังจากเริ่มคำสั่งที่แนบมากับ ssh: ssh host "command เพื่อเรียกใช้บนเครื่องโฮสต์> / dev / null &" ฉันไม่เข้าใจเหตุผลที่คำสั่งนี้บังคับให้เชื่อมต่อกับ ใกล้เสร็จแล้ว แต่อย่างน้อยมันก็มีประโยชน์สำหรับฉัน หากใครเข้าใจการชี้นำของเอาต์พุตของคำสั่งไปที่ / dev / null และทำไมมันถึงฆ่าการเชื่อมต่อ ssh มันจะดีถ้าเขา / เธอสามารถอธิบายได้ :-)
coffeMug

คำสั่ง ssh host "เพื่อเรียกใช้บนเครื่องโฮสต์> / dev / null &"
coffeMug

1
มันไม่ได้เป็นคำตอบสำหรับคำถามนี้ แต่มันมีประโยชน์ที่จะทราบต่อไป: ไคลเอนต์ SSH มีชุดของตัวควบคุมที่สามารถนำมาใช้เพื่อฆ่าลูกค้า Enterตัวควบคุมได้รับการยอมรับเพียงทันทีหลังจากการขึ้นบรรทัดใหม่เพื่อเริ่มต้นโดยการกด จากนั้นเช่น~.จะยุติเซสชัน Enter ~?สำหรับรายการของผู้อื่น
Tom

คำตอบ:


22

คำสั่งreboot -fจะไม่ส่งคืน (เว้นแต่ว่าคุณไม่ได้รับอนุญาตให้ทำการรีบูต) ณ จุดที่มีการออกไคลเอนต์ SSH กำลังรอสิ่งที่จะทำซึ่งอาจเป็น:

  • เซิร์ฟเวอร์ SSH แจ้งลูกค้าว่ามีบางสิ่งเกิดขึ้นที่ต้องการความสนใจตัวอย่างเช่นมีเอาต์พุตบางส่วนที่จะแสดงหรือว่าคำสั่งรีโมตเสร็จสิ้นแล้ว
  • เหตุการณ์บางอย่างที่ฝั่งไคลเอ็นต์เช่นสัญญาณเพื่อถ่ายทอด
  • ตัวจับเวลาเริ่มทำงานเพื่อให้ไคลเอ็นต์ส่งข้อความแบบ keepalive (และปิดการเชื่อมต่อหากเซิร์ฟเวอร์ไม่ตอบกลับ)

เนื่องจากกระบวนการเซิร์ฟเวอร์ SSH นั้นตายแล้วไคลเอ็นต์ SSH จะไม่ตายจนกว่าตัวจับเวลาจะเริ่มทำงาน

หากคุณทำงานssh remotehost 'reboot -f >/dev/null &'แล้วสิ่งที่เกิดขึ้นคือ:

  1. เปลือกระยะไกลเปิดตัวrebootคำสั่งในพื้นหลัง
  2. เนื่องจากคำสั่งเชลล์ฝั่งเซิร์ฟเวอร์ออกแล้วและไม่มีกระบวนการเก็บไฟล์ descriptor สำหรับเอาต์พุตมาตรฐานเปิดเซิร์ฟเวอร์ SSH จะปิดการเชื่อมต่อ
  3. rebootคำสั่งเป็นสาเหตุที่ทำให้เครื่องที่จะรีบูต

อย่างไรก็ตามสิ่งนี้ไม่น่าเชื่อถือ: ขึ้นอยู่กับเวลาขั้นตอนที่ 3 อาจเกิดขึ้นก่อนขั้นตอนที่ 2 การเพิ่มตัวจับเวลาทำให้สิ่งนี้ไม่น่าเป็นไปได้:

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

เพื่อให้แน่ใจอย่างแน่นอนว่าฝั่งเซิร์ฟเวอร์มุ่งมั่นที่จะทำงานrebootในขณะที่ตรวจสอบให้แน่ใจว่าไม่ได้รีบูตจริงก่อนที่จะแจ้งให้ลูกค้าทราบว่ามีการมุ่งมั่นคุณต้องมีการแจ้งเตือนเพิ่มเติมจากเซิร์ฟเวอร์ไปยังไคลเอนต์ สิ่งนี้สามารถส่งออกผ่านการเชื่อมต่อ SSH แต่มันก็ซับซ้อน


2
ในกรณีที่ใครที่กำลังมองหาวิธีที่จะทำเช่นนี้จากภายในพื้นที่ห่างไกล (วิธีการแก้ปัญหาที่คล้ายกัน) (sleep 1 && sudo reboot &) && exitA: วงเล็บจะวางกระบวนการย่อยซึ่งจะรอหนึ่งวินาทีจากนั้นเริ่มต้นการรีบูต กระบวนการโฮสต์จะยุติเซสชัน ssh ทันที ฉันไม่ได้เป็นกูรูเปลือก แต่สิ่งนี้ได้ผลสำหรับฉันจนถึงตอนนี้
Griddo

@Griddo มันใช้งานได้ดีและเป็นแฮ็คเล็ก ๆ ที่เรียบร้อย ฉันรักมัน. ขอบคุณสำหรับการแบ่งปัน!
Joshua Pinter

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 จะยุติการเชื่อมต่อโดยไม่มีข้อผิดพลาด


1

ฉันใช้คำสั่งต่อไปนี้:

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

นี่คือสิ่งที่ทำ:

  • มันบอกให้เครื่องรีบูตในช่วงเวลาต่อไป แต่ไม่ใช่ในช่วงคำสั่งนี้
  • ออกจากหมดจดจาก SSH
  • รักษา SSH TTY ตลอดเวลาเพื่อให้ sudo มีความสุขและสามารถทำงานได้อย่างถูกต้อง

0

คุณได้ลองสิ่งต่อไปนี้แล้วหรือยัง

# shutdown -r now

ฉันพบว่าในบางระบบที่ฉันทำงานด้วยในการผ่านคำสั่งรีบูตมีปัญหาบางอย่าง จากนั้นอีกครั้งฉันไม่พบสิ่งใดใน manpage ของการปิดที่จะทำเหมือนกับรีบูตด้วยแฟล็ก -f


1
ใช่การปิดระบบไม่ทำงานในเครื่องที่ฉันพยายามเชื่อมต่อด้วยเหตุผลแปลก ๆ นั่นคือเหตุผลที่ฉันใช้ reboot -f เพื่อบังคับให้ปิดและรีสตาร์ท
coffeMug

0

วิธีการเกี่ยวกับ exit จาก ssh session และ reboot system โดยใช้คำสั่งถัดไป:

ssh login@host "reboot -f"

หลังจากนี้เพียงกด Ctrl + C เพื่อยุติ ssh


0

ฉันพบวิธีแก้ปัญหาสำหรับสิ่งนี้ซึ่งอาจเป็นประโยชน์สำหรับผู้อื่นเช่นกัน ฉันใช้คำสั่งต่อไปนี้เพื่อปิดการเชื่อมต่อทันทีหลังจากเริ่มคำสั่งที่แนบมากับ ssh:

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

ฉันไม่เข้าใจเหตุผลที่คำสั่งนี้บังคับให้ปิดการเชื่อมต่อ แต่อย่างน้อยมันก็มีประโยชน์สำหรับฉัน หากใครเข้าใจว่าทำไมมันถึงฆ่าการเชื่อมต่อ ssh; กรุณาอธิบาย.


0

ต้องใช้เวลาล่าช้า 1 นาที แต่ทำงานได้อย่างน่าเชื่อถือสำหรับฉันและแก้ปัญหาแฮงค์ไคลเอ็นต์ SSH:

    $ sudo shutdown +1; logout

นี่จะกำหนดเวลาการปิดระบบเป็นเวลา 1 นาทีในภายหลังซึ่งจะช่วยให้เวลาสำหรับการออกจากระบบและการเลิกจ้าง SSH จึงจะเสร็จสมบูรณ์ หากคุณต้องการรอเวลาน้อยที่สุดเท่าที่จะทำได้คุณสามารถแทนที่+1ด้วยHH:MMสำหรับช่วงเวลาที่ใกล้เข้ามาอย่างรวดเร็วของวัน แต่นั่นอาจเป็นเรื่องยากที่จะใช้เวลาอย่างถูกต้องและอาจล่าช้าถึง 59 วินาที


0

วิธีง่าย ๆ ที่ฉันได้พบคือการสั่งปิด / รีบูตเป็นงานพื้นหลัง (ใช้ '&'), ปกป้องมันจากการถูกปิดเมื่อเซสชั่นปิดด้วย 'nohup' พร้อมกับออกจากเปลือก / เซสชันทันที:

nohup shutdown -r now & exit

ด้วยวิธีนี้ไคลเอ็นต์ SSH จะไม่หยุดทำงานเนื่องจากเซสชันออกทันทีในขณะที่ระบบรีโมตดำเนินต่อด้วยการรีบูตแบบอะซิงโครนัส


หรือทดแทนระบบที่เทียบเท่ากับ "shutdown -r now" เพื่อรีบูต ....
MikeW

-2

ลองคำสั่งนี้:

$ reboot -f && exit

2
น่าเสียดายที่นี่ใช้งานไม่ได้
coffeMug

1
@AKh_Sw เจาะจงว่า "ไม่ทำงาน"
gertvdijk

@AKh_Sw: หากคุณพิมพ์เครื่องหมาย '$' จะไม่สามารถใช้งานได้
tH0r

1
ไร้ประโยชน์ reboot -fตรงนี้เป็นเทียบเท่ากับ
Gilles 'หยุดความชั่วร้าย'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.