ป้องกันหน้าจอ GNU จากการยกเลิกเซสชันเมื่อสคริปต์ทำงานสิ้นสุดลง


34

ฉันพยายามบังคับให้หน้าจอ GNU สร้างเทอร์มินัล "เสมือน" โดยไม่ต้องเชื่อมต่อกับมันรันสคริปต์ภายในและไม่หยุดเซสชันเมื่อสคริปต์สิ้นสุดลง

ฉันลองชุดค่าผสมมากมายรวมถึง:

screen -dmS udplistener /share/Sys/autorun/start_udp_listeners.sh

หรือ

screen -S udplistener -X /share/Sys/autorun/start_udp_listeners.sh

และไม่มีใครทำงาน ฉันได้รับเซสชันโดยไม่มีสคริปต์ที่ดำเนินการสคริปต์จะดำเนินการ แต่เซสชันจะสิ้นสุดลงเมื่อเสร็จสิ้นหรือฉันได้รับข้อผิดพลาด "ไม่พบเซสชันหน้าจอ"

สิ่งที่ฉันพยายามทำอยู่ก็คือรัน UDP listener ที่เขียนด้วย PHP และทำให้มันทำงานใน infinte loop (อย่าหยุดฟัง) ใช่ - ฉันสามารถเรียกใช้สคริปต์ PHP ด้วย&ในตอนท้ายบังคับให้ PHP CLI ทำงานเป็น daemon ปัญหาคือว่าฉันกำลังใช้ชิ้นส่วนของขยะที่เรียกว่าเซิร์ฟเวอร์ (QNAP - ไม่เคยซื้อขยะนี้!) ซึ่งดูเหมือนจะไม่สนใจสิ่งนี้ ทันทีที่ฉันออกจากเซสชัน SSH สคริปต์จะหยุดทำงาน

ดังนั้นscreenดูเหมือนจะเป็นตัวเลือกเท่านั้น แต่ฉันไม่เข้าใจว่าทำไมมันถึงเลิกเซสชันเมื่อคำสั่งหรือสคริปต์สิ้นสุดลง

แก้ไข : ฉันได้ลองตัวอย่างที่พบในอินเทอร์เน็ต:

screen -dmS name
screen -S name -p windowname -X stuff 'mc
'

ไม่ขาด! หลังจากติดมัน ( screen -R name) ฉันเห็นว่า Midnight Commander HASN'T ไม่ถูกประหารชีวิต แม้ว่าผู้เขียนตัวอย่างกล่าวว่ามันจะเป็น


วิธีที่คุณเรียกใช้screenคุณสร้างเพียงหน้าต่างเดียวเพื่อเรียกใช้คำสั่งเดียว เมื่อคำสั่งออกจากหน้าต่างจะปิดและscreenไม่มีอะไรเหลือให้ทำดังนั้นจึงจะออก
jw013

ดังนั้น ... มีวิธีการเปิดหน้าต่างสองบาน (โดยใช้บรรทัดคำสั่งเท่านั้นไม่มีชุดแป้นพิมพ์) หนึ่งเพื่อรันสคริปต์และวินาทีเพื่อป้องกันการscreenปิด? BTW: ฉันยังไม่เข้าใจความคิด! ถ้าฉันโทรscreen -dmS nameฉันจะสร้างหน้าต่างแยกออกซึ่งไม่มีอะไรเหลือให้ทำ แต่มันจะไม่ปิดอัตโนมัติ! แต่เมื่อฉันต้องการรันบางสิ่งในหน้าจอที่แยกออกมามันจะสิ้นสุดลงเมื่อการประมวลผลเสร็จสิ้น ทำไม? ฉันไม่เห็นเหตุผลที่นี่ มีหน้าต่างที่ไม่ทำอะไรเลย แต่ไม่มีหน้าต่างทำอะไรแล้วไม่ทำอะไรเลย?
trejder

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

เย็น! ขอบคุณสำหรับคำอธิบาย! ดังนั้น ... กลับไปที่คำถาม ... มีวิธีใดบ้างในการรันคำสั่งภายในหน้าจอ / หน้าต่างที่แยกออกมาและไม่หยุดเซสชันนั้นเมื่อการประมวลผลคำสั่งสิ้นสุดลง? นอกจากนี้โปรดดูคำถามล่าสุด ขอขอบคุณ.
trejder

สคริปต์นี้กำลังเรียกใช้ตัวรับฟัง UDP สองตัวที่เขียนด้วย PHP แม้ว่าทั้งสองจะดำเนินการเป็นภูต (มี&ที่สิ้นสุด) เนื่องจากเซิร์ฟเวอร์รถ (QNAP) พวกเขากำลังจะสิ้นสุดลงเมื่อสิ้นสุดเซสชัน (ผมบอกพวกเขาควรจะไม่ได้อยู่ในลินุกซ์ปกติถ้าดำเนินการด้วย&) ดังนั้นฉันไม่ต้องการทำอะไรหลังจากstart_udp_listeners.shเสร็จสิ้นมีเพียงวิธีการป้องกันไม่ให้เซสชั่นสิ้นสุดลง ตราบใดที่มันไม่เป็นเช่นนั้นผู้ฟัง PHP ของฉันก็ใช้งานได้ดี
trejder

คำตอบ:


42

หากต้องการให้หน้าจอไม่ทำงานหลังจากสคริปต์ทำงานเสร็จให้ทำบางสิ่งบางอย่างค้างไว้ในหน้าต่าง ตัวเลือกที่ง่ายที่สุดสำหรับ "บางสิ่ง" นั้นน่าจะเป็นเชลล์แบบโต้ตอบ ต่อไปนี้เป็นวิธีหนึ่งในการดำเนินการ (สมมติว่าbashเป็นตัวเลือกของเชลล์แบบโต้ตอบ):

screen -dmS session_name sh -c '/share/Sys/autorun/start_udp_listeners.sh; exec bash'
  • -dm: เริ่มหน้าจอในโหมดเดี่ยว
  • -S: ตั้งค่าชื่อเซสชันสำหรับหน้าจอเพื่อให้เรียกใช้ได้ง่ายขึ้นในภายหลัง
  • sh -c '...': แทนที่จะเรียกใช้สคริปต์ของคุณซึ่งจะยุติใช้sh -cเพื่อเรียกใช้หลายคำสั่ง
  • exec bash: หลังจากสคริปต์หยุดทำงาน, shจากด้านบนจะเปลี่ยนเป็นเชลล์แบบโต้ตอบ ( bash), ซึ่งไม่ควรออกจนกว่าบางสิ่งภายนอกจะจบลง สิ่งนี้จะscreenเปิดไว้ตราบใดที่bashอินสแตนซ์ยังมีชีวิตอยู่

1
หืม ... ดูเหมือนคุณจะเป็นผู้ช่วยชีวิตของฉัน! :] การขยายโซลูชันของคุณด้วยexport IGNOREEOF=1เพื่อป้องกันการเลิกจ้างโดยบังเอิญด้วย Ctrl + D ควรให้โซลูชันที่สมบูรณ์แบบแก่ฉันฉันกำลังมองหาช่วงเย็นที่ยาวนาน ขอขอบคุณ! :]
trejder

สิ่งนี้ไม่สามารถใช้กับ Debian ได้ในวันนี้ -c เป็นอาร์กิวเมนต์ในการอ่านไฟล์. screenrc ทางเลือก ...
ToVine

@ToVine ทำงานได้อย่างสมบูรณ์บน Debian Stable (Wheezy) ผมใช้bash -cแต่
TranslucentCloud

@TranslucentCloud คุณใส่คำสั่งทั้งหมด "bash -c ... " ในเครื่องหมายคำพูดหรือไม่ ครั้งสุดท้ายที่ฉันลอง (ขวาก่อนที่จะเขียนความคิดเห็น) มันไม่ทำงานสำหรับฉันไม่แน่ใจว่าทำไม ...
ToVine

@ ToVine นี่คือคำสั่งทั้งหมดของฉัน:screen -LS sauf bash -c "sudo aptitude update && sudo aptitude full-upgrade; exec bash"
TranslucentCloud

2

ฉันไม่มีโชคกับsh -craspberry pi 2 ของฉันที่ใช้ Debian 7.8 แต่bash -cทำงาน:

คำสั่ง:

/usr/bin/screen -dmS test-screen bash -c "/usr/bin/top; exec bash"

อาจเป็นเพราะคุณกำลังใช้ (บน Raspberry Pi) เป็นเปลือกที่แตกต่างกันหรือไม่ bashและshดูเหมือนว่าจะเป็นเปลือกหอยสองที่แตกต่างกัน นั่นคือทั้งหมดที่ฉันคิดว่า แต่ฉันอาจจะผิดเพราะฉันเป็นมือใหม่ที่ Linux ทั้งหมด
trejder

1
sh เป็นค่าเริ่มต้นยูนิกซ์เชลล์มันรวมอยู่ใน raspbian (debian) คำสั่ง sh ยังใช้งานได้ แต่ไม่ใช่ sh -c ร่วมกับหน้าจอ
scotty86

ขอบคุณ @ scotty86 ผมสังเกตเดียวกันในลินุกซ์มิ้นท์ 19 (Ubuntu 18.04) และการเปลี่ยนแปลงsh -cที่จะbash -cได้เคล็ดลับ ฉันไม่เข้าใจว่าทำไมทั้งคู่shและbashติดตั้งแล้วดังนั้นฉันยังคงนอนไม่หลับ แต่อย่างน้อยก็ใช้งานได้
Redsandro

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