การจัดการ Ctrl-C ในเซสชัน SSH


20

เมื่อฉันเริ่มเซสชัน SSH ที่ดำเนินการคำสั่งที่ใช้เวลานานจะเกิดอะไรขึ้นกับการจัดการCtrl+ C(SIGINT)

ฉันเห็นว่าเซสชัน SSH ถูกปิด แต่ฉันไม่แน่ใจว่าใครจะได้รับ SIGINT ก่อน: ใช่หรือไม่

  1. คำสั่งที่ทำงานระยะไกลระยะไกล? นั่นคือ (a) ตัวจัดการสัญญาณในคำสั่งรีโมตถูกเรียกและหยุดคำสั่งรีโมต (b) เชลล์ที่วางไข่ตรวจพบว่าคำสั่งหยุดทำงานและหยุดเช่นกัน (c) sshd รีโมตตรวจจับเชลล์หยุด ดังนั้นจึงปิดการเชื่อมต่อ

    หรือ

  2. ssh ท้องถิ่นได้รับสัญญาณและปิดการเชื่อมต่อ

ฉันคิดว่า (1) กำลังเกิดขึ้น แต่ต้องการตรวจสอบให้แน่ใจ

ฉันยังไม่แน่ใจเกี่ยวกับสิ่งที่เกิดขึ้นกับการจัดการเชลล์ของ SIGINT ในกรณีนี้ ตัวอย่างเช่นถ้าฉัน ...

ssh remote 'while true ; do sleep 1 ; date ; done'

และCtrl+ Cจากนั้นการเชื่อมต่อระยะไกลจะลดลง มีวิธีเรียกใช้คำสั่งระยะไกลภายใต้เปลือกที่จะมีชีวิตอยู่หลังจากCtrl+ C? นั่นคือในกรณีนี้หยุดลูปและอนุญาตให้ฉันทำงานบนเปลือกระยะไกลหรือไม่


3
ssh ที่ไม่ทำปฏิกิริยา ( ssh remote command, ตรงข้ามกับssh remote) จะถูกฆ่า (บนโลคัล) โดย SIGINT ที่สร้างโดยการพิมพ์ ctrl-C ด้านระยะไกลอาจจะ (ขึ้นอยู่กับระบบปฏิบัติการ) ยังคงทำงานจนกว่าจะพยายามอ่านหรือเขียนไปยังซ็อกเก็ตปิด หากคุณต้องการการกดแป้นพิมพ์ของคุณทั้งหมดรวมทั้ง Ctrl-C ssh remoteจะได้รับการส่งต่อไปยังที่ห่างไกลการใช้
Mark Plotnick

@MarkPlotnick: ตกลงทำเครื่องหมาย - ถ้าคุณเพิ่มคำตอบของคุณด้านล่างเป็นคำตอบฉันจะยอมรับ ... ในการทดสอบของฉันเองฉันตรวจสอบว่าระยะไกลไม่ได้รับสัญญาณใด ๆ
ttsiodras

คำตอบ:


23

sshสามารถเรียกใช้ด้วยวิธีที่ต่างกันสองสามวิธีแต่ละวิธีทำให้เกิดสัญญาณต่าง ๆ ที่เริ่มจากเทอร์มินัลเล็กน้อยเช่นCtrl-Cกัน

  • ssh remotehostremotehostจะทำงานเซสชั่นแบบโต้ตอบบน ในฝั่งไคลเอ็นต์sshจะพยายามตั้งค่า tty ที่ใช้โดย stdin เป็นโหมด "raw" และsshdบนรีโมตโฮสต์จะจัดสรร pseudo-tty และรันเชลล์ของคุณเป็นเชลล์ล็อกอิน (เช่น-bash)

    การตั้งค่าโหมด raw หมายความว่าอักขระที่ปกติจะส่งสัญญาณ (เช่นCtrl-CและCtrl-\) จะถูกแทรกเข้าไปในกระแสข้อมูลแทน sshจะส่งตัวอักษรตามที่เป็นไปยังรีโมตโฮสต์โดยที่พวกมันจะส่ง SIGINT หรือ SIGQUIT และโดยทั่วไปจะฆ่าคำสั่งใด ๆ และส่งคุณกลับไปที่เชลล์บนรีโมตโฮสต์ การเชื่อมต่อ ssh จะยังคงอยู่ตราบใดที่เปลือกระยะไกลยังมีชีวิตอยู่

  • ssh -t remotehost command args ...จะเรียกใช้เซสชั่นแบบโต้ตอบremotehostเช่นเดียวกับข้างต้นยกเว้นในด้านระยะไกลyour_shell -c "command args ..."จะถูกเรียกใช้ ดังที่กล่าวมาข้างต้นหากคุณพิมพ์Ctrl-Cคำสั่งจะถูกส่งไปยังรีโมตโฮสต์โดยที่คำสั่งจะรับ SIGINT และออกทันทีจากนั้นรีโมตเชลล์จะออก จากsshdนั้นรีโมตปิดการเชื่อมต่อและsshรายงานConnection to remotehost closed.

  • ssh remotehost command args ...remotehostจะทำงานเซสชั่นที่ไม่ใช่แบบโต้ตอบบน ทางฝั่งไคลเอ็นต์sshจะไม่ตั้งค่า tty เป็นโหมด raw (ดียกเว้นการอ่านในรหัสผ่านหรือวลีรหัสผ่าน) ถ้าคุณพิมพ์Ctrl-C, sshจะได้รับการส่ง SIGINT และจะถูกยกเลิกทันทีโดยไม่ต้องออกConnection to remotehost closedข้อความ

    your_shell -c "command args ..."กระบวนการจะมีแนวโน้มที่จะยังคงทำงานในพื้นที่ห่างไกล ไม่ว่าพวกเขาจะออกด้วยตัวเองหรือหนึ่งกระบวนการจะพยายามเขียนข้อมูลไปยังซ็อกเก็ต ssh ปิดตอนนี้ซึ่งจะทำให้สัญญาณ SIGPIPE ร้ายแรง (โดยทั่วไป) จะถูกส่งไปยังมัน


1
ในทางเทคนิคแล้วคำสั่งระยะไกลไม่ได้เขียนโดยตรงไปยังซ็อกเก็ต stdout มันเป็นท่อ และ sshd ที่ปลายอีกด้านหนึ่งอ่านข้อมูลเข้ารหัสและส่งข้อมูลผ่านซ็อกเก็ต ผลลัพธ์ที่ได้ก็เหมือนกัน คำสั่งจะได้รับ sigpipe เนื่องจากไปป์นั้นหายไปเมื่อลูกค้ายกเลิกการเชื่อมต่อ
Stéphane Chazelas

@ StéphaneChazelasขอบคุณฉันจะแก้ไขคำตอบเพื่อแก้ไข
Mark Plotnick
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.