วิธีการยุติแบบระยะไกลเรียกว่า“ tail -f” เมื่อการเชื่อมต่อถูกปิด


24

ฉันเพิ่งสังเกตเห็นว่าถ้าฉันรันssh user@remote_host tail -f /some/fileแล้วtail -f /some/fileยังคงทำงานบน remote_host แม้ว่าการเชื่อมต่อ ssh ถูกปิด!

ดังนั้นหลังจากหลายการเชื่อมต่อและยกเลิกการเชื่อมต่อจำนวนการทำงานtail -f /some/fileจะเพิ่มขึ้น วิธีการยุติจริงtail -fเมื่อการเชื่อมต่อ ssh ถูกปิด?

คำตอบ:


33

ใน

ssh host tail -f file

sshลูกค้าเชื่อมต่อกับsshdเซิร์ฟเวอร์hostผ่านการเชื่อมต่อ TCP sshdทำงานtail -fด้วย stdout ที่เปลี่ยนเส้นทางไปยังไปป์ sshdอ่านสิ่งที่มาจากปลายอีกด้านหนึ่งของไปป์และสรุปในโพรโทคอล sshd เพื่อส่งไปยังsshไคลเอนต์ (มีrshd, tailstdout จะได้รับซ็อกเก็ตโดยตรง แต่sshdเพิ่มการเข้ารหัสและสามารถที่จะ multiplex ลำธารหลาย (เช่นพอร์ต / ตัวแทน / X11 / เปลี่ยนเส้นทางอุโมงค์ stderr) ในการเชื่อมต่อ TCP เดียวเพื่อมีรีสอร์ทเพื่อท่อ)

เมื่อคุณกด CTRL-C SIGINT จะถูกส่งไปยังsshลูกค้า ที่ทำให้เกิดsshการตาย เมื่อกำลังจะตายการเชื่อมต่อ TCP จะถูกปิด และดังนั้นบนhost, sshdตายเช่นกัน tailไม่ได้ถูกฆ่า แต่ stdout ของมันตอนนี้เป็นไพพ์ที่ไม่มีตัวอ่านที่ปลายอีกด้าน ดังนั้นในครั้งต่อไปที่มันเขียนอะไรบางอย่างไปยัง stdout มันจะได้รับ SIGPIPE และตาย

ใน:

ssh -t host 'tail -f file'

มันเป็นสิ่งเดียวกันยกเว้นว่าแทนที่จะอยู่กับไพพ์การสื่อสารระหว่างsshdและtailผ่านเทอร์มินัลหลอก tail's stdout เป็นทาสหลอก terminal (เช่น/dev/pts/12) และสิ่งที่tailเขียนมีอยู่readในด้านต้นแบบ (อาจแก้ไขได้โดยวินัยบรรทัด tty) โดยsshdและส่งห่อหุ้มไปยังsshลูกค้า

ที่ฝั่งไคลเอ็นต์ด้วย-t, ให้sshวางเทอร์มินัลในrawโหมด โดยเฉพาะอย่างยิ่งที่ปิดใช้งานโหมดบัญญัติและการจัดการสัญญาณเทอร์มินัล

ดังนั้นเมื่อคุณกดCtrl+Cแทนวินัยของเทอร์มินัลไลน์ของลูกค้าที่ส่ง SIGINT ไปยังsshงานนั่นก็แค่ส่ง^Cตัวละครผ่านการเชื่อมต่อไปยังsshdและsshdเขียน^Cไปยังฝั่งมาสเตอร์ของรีโมตเทอร์มินัล และมีระเบียบวินัยสายของขั้วระยะไกลส่งไปSIGINT จากนั้นจะตายและออกจากและปิดการเชื่อมต่อและยุติ (หากยังไม่ได้ยุ่งกับการส่งต่อพอร์ตหรืออื่น ๆ )tailtailsshdssh

นอกจากนี้-tหากsshลูกค้าตาย (เช่นหากคุณป้อน~.) การเชื่อมต่อจะปิดและsshdตาย ในฐานะที่เป็นผลให้ SIGHUP tailจะถูกส่งไป

ตอนนี้ระวังว่าการใช้-tมีผลข้างเคียง ตัวอย่างเช่นด้วยการตั้งค่าเทอร์มินัลเริ่มต้น\nตัวละครจะถูกแปลง\r\nและอาจมีสิ่งต่าง ๆ เกิดขึ้นอีกมากมายขึ้นอยู่กับระบบรีโมตดังนั้นคุณอาจต้องการที่จะออกstty -opost(เพื่อปิดการใช้งานการประมวลผลเอาต์พุต) บนรีโมตโฮสต์ ขั้ว:

$ ssh  localhost 'echo x' | hd
00000000  78 0a                                             |x.|
00000002
$ ssh -t localhost 'echo x' | hd
00000000  78 0d 0a                                          |x..|
00000003
$ ssh -t localhost 'stty -opost; echo x' | hd
00000000  78 0a                                             |x.|
00000002

ข้อเสียเปรียบอีกประการของการใช้-t/ -ttคือ stdout และ stderr ไม่ได้แยกความแตกต่างบนไคลเอนต์ ทั้ง stdout และ stderr ของคำสั่งระยะไกลจะถูกเขียนไปยังsshstdout ของลูกค้า:

$ ssh localhost ls /x  | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1

ขอบคุณมากสำหรับคำอธิบายอย่างละเอียด! ฉันหวังว่าฉันจะยอมรับคำตอบได้สองข้อ ..
มิทรีแฟรงค์ใน

"ด้วย-tหากsshลูกค้าตาย (เช่นถ้าคุณป้อน~.)" จะเกิดอะไรขึ้น~.?
x-yuri

1
@ x-yuri ~.เป็นลำดับ escape ที่คุณป้อนเพื่อยกเลิกการเชื่อมต่อไคลเอ็นต์ ดูman sshรายละเอียดที่
Stéphane Chazelas

11

คุณต้องการการจัดสรรเทอร์มินัลที่ด้านระยะไกล:

ssh -t user@remote_host tail -f /some/file

หรือแม้กระทั่ง

ssh -tt user@remote_host tail -f /some/file

1
ขอบคุณทั้งสอง-tหรือใช้-ttงานได้ แต่ฉันก็ยังไม่เข้าใจเหตุผลที่แท้จริงของสิ่งนี้: พูดเมื่อฉันเรียกเชลล์จากระยะไกลและปิดการเชื่อมต่อเชลล์จะถูกยกเลิก แต่tail -fไม่ใช่ แน่นอนฉันได้อ่านเกี่ยวกับ-tตัวเลือกในman sshแล้ว แต่มันก็ไม่ได้ช่วยอะไรมาก ดูเหมือนว่าฉันไม่เข้าใจยาชื่อสามัญและฉันยินดีที่คุณแนะนำเอกสารให้อ่านหรืออธิบายด้วยตัวเอง ขอบคุณ!
Dmitry Frank

2
เข้าใจ @DmitryFrank ของฉันนี้หากแบ่งการเชื่อมต่อแล้วส่งsshd SIGHUPแต่ที่ไม่เป็นขั้วจะต้องไม่มี hangup การเชื่อมต่อขั้ว ...
Hauke Laging

ขอบคุณฉันจะอ่านเกี่ยวกับSIGHUPและสัญญาณอื่น ๆ ยังไม่รู้อะไรเกี่ยวกับมัน
Dmitry Frank

fyi: ฉันแค่พยายามวิ่งtail -fแล้วฉันก็เปิดhtopและส่งSIGHUPมัน (โดยการกดF9-> 1-> Enter) และtail -fถูกยกเลิก! ดังนั้นเหตุผลที่ควรจะแตกต่างกันบาง ..
มิทรีแฟรงก์

3
@DmitryFrank คุณเข้าใจผิดปัญหาแล้ว ปัญหาคือไม่ได้ที่จะไม่ตอบสนองต่อการtail SIGHUPปัญหาคือว่าSIGHUP** ไม่ถูกส่งไปที่tailไม่มีเทอร์มินัลหลอก คุณจะเห็นว่าโดยการแนบstraceไปtailในทั้งสองกรณี
Hauke ​​Laging
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.