ทำไม SSH ไม่รอกระบวนการพื้นหลัง


13

ทำไมมันssh -tไม่รอให้งานพื้นหลังเสร็จ?

ตัวอย่าง:

ssh user@example 'sleep 2 &'

ใช้งานได้ตามที่คาดไว้เนื่องจาก ssh กลับมาหลังจาก 2 วินาทีในขณะที่

ssh user@example -t 'sleep 2 &'

ไม่รอsleepให้เสร็จและส่งคืนทันที

ทุกคนสามารถอธิบายเหตุผลที่อยู่เบื้องหลังสิ่งนี้ได้ไหม มีวิธีssh -tรอกระบวนการพื้นหลังทั้งหมดให้เสร็จก่อนที่จะส่งคืนหรือไม่

กรณีการใช้งานของฉันคือฉันเริ่มต้นสคริปต์ด้วยssh -tและสคริปต์นี้เริ่มงานพื้นหลังต่าง ๆ ที่ควรมีชีวิตอยู่หลังจากสคริปต์หลักเสร็จสิ้น ด้วยssh -tสิ่งนี้เป็นไปไม่ได้จนถึงตอนนี้

คำตอบ:


22

หากไม่มี-tให้sshdรับ stdout ของ remote shell (และ children like sleep) และ stderr ผ่านสองไพพ์ (และยังส่งอินพุตของลูกค้าผ่านไพพ์อื่น)

sshd ไม่รอให้กระบวนการที่มันได้เริ่มต้นเข้าสู่ระบบเชลล์ของผู้ใช้ แต่ยังหลังจากที่กระบวนการได้ยุติการรอ eof บนท่อ stdout (ไม่ใช่ท่อ stderr ในกรณีของ openssh อย่างน้อย)

และ eof เกิดขึ้นเมื่อไม่มีตัวบ่งชี้ไฟล์โดยกระบวนการใด ๆ ที่เปิดอยู่ที่ปลายการเขียนของไพพ์ซึ่งโดยทั่วไปจะเกิดขึ้นเมื่อกระบวนการทั้งหมดที่ไม่มี stdout ถูกเปลี่ยนเส้นทางไปยังสิ่งอื่นหายไป

เมื่อคุณใช้-t, sshdไม่ได้ใช้ท่อ แต่การโต้ตอบทั้งหมด (stdin, stdout, stderr) กับเชลล์ระยะไกลและลูก ๆ จะทำได้โดยใช้คู่หลอกขั้ว

ด้วยคู่เทอร์มินัลหลอกสำหรับsshdการโต้ตอบกับฝั่งมาสเตอร์ไม่มีวิธีการจัดการ eof ที่คล้ายกันหรือวิธีการใด ๆ ที่จะรู้ว่ายังมีกระบวนการที่ fds เปิดไปด้านทาสของเทอร์มินัลหลอกดังนั้นมันแค่รอการยุติ กระบวนการที่ดำเนินการเชลล์ล็อกอินของผู้ใช้รีโมตจากนั้นออก

เมื่อออกจากนั้นมาสเตอร์หลักของ pty pair จะถูกปิดซึ่งหมายความว่า pty ถูกทำลายดังนั้นกระบวนการที่ควบคุมโดย slave จะได้รับ SIGHUP (ซึ่งโดยค่าเริ่มต้นจะยุติพวกเขา)


1
ขอบคุณสำหรับคำตอบอย่างละเอียด! สิ่งอื่นที่ฉันต้องการทราบ: กระบวนการพื้นหลังทั้งหมดยุติลงเมื่อเทอร์มินัลหลอกออกหรือไม่ สคริปต์ที่ฉันเริ่มต้นจะเริ่มให้บริการซึ่งทำงานได้ดีกับ ssh แต่เมื่อใช้ ssh -t บริการจะไม่เริ่มทำงาน ดูเหมือนว่าบริการจะปิดตัวลงเมื่อ ssh กลับมา
Philipp Murry

ที่จริงแล้วมีวิธีสำหรับฝั่งมาสเตอร์ของเทอร์มินัลเทียมหลอกที่จะรู้ว่าเมื่อใดที่ไฟล์ descriptors ทาสทั้งหมดถูกปิด มันเป็นกลไกแบบเดียวกันที่ถูกเรียกใช้โดยเทอร์มินัลจริงเมื่อตัวอธิบายไฟล์ทั้งหมดถูกปิดในความเป็นจริง
JdeBP


@JdeBP คุณต้องการขยายหรือไม่ ฉันไม่แน่ใจว่าคุณหมายถึงอะไร เทอร์มินัลอีมูเลเตอร์ AFAICT (อย่างน้อย xterm และ gnome-terminal) ไม่สนใจเกี่ยวกับกระบวนการที่ยังคงมี fds เปิดให้ทาสเมื่อกระบวนการที่พวกเขาดำเนินการเชลล์ในตาย
Stéphane Chazelas

@PhilippMurry คุณสามารถใช้nohupเพื่อให้สคริปต์ทำงานเช่นนั้น (คุณยังอาจพิจารณาเริ่มต้นงานยาวทำงานภายในของtmuxเพื่อให้คุณสามารถติดตามความคืบหน้าของพวกเขาโต้ตอบ แต่ไฟล์บันทึกการทำงานที่ดี.)
jpaugh

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