ฉันจะแนบเซสชัน Mosh ที่แยกออกมาใหม่ได้อย่างไร


157

ฉันจะใส่กลับไปที่เซสชัน mosh ที่แยกออกหรืออย่างอื่นได้อย่างไร

Mosh: You have a detached Mosh session on this server (mosh [XXXX]).

นั่นคือสิ่งที่เทียบเท่า mosh ของ

screen -D -R

หรืออาจจะเป็น

screen -wipe

นอกจากนี้คำตอบนี้สามารถพบได้ในเอกสารประกอบ?

คำตอบ:


197

เพื่อเหตุผลด้านความปลอดภัยคุณไม่สามารถติดตั้งใหม่ได้โปรดดูhttps://github.com/keithw/mosh/issues/394

หากต้องการฆ่าเซสชันที่แยกออกให้ใช้หมายเลข PID ที่แสดงในข้อความนั้น (นั่นคือส่วน 'XXXX') ตัวอย่างเช่นหากคุณเห็น -

Mosh: You have a detached Mosh session on this server (mosh [12345]).

และสามารถเรียกใช้คำสั่งนี้:

kill 12345

นอกจากนี้หากต้องการปิดการเชื่อมต่อ mosh ทั้งหมดคุณสามารถ:

kill `pidof mosh-server`

โปรดทราบว่าหากคุณกำลังเชื่อมต่อผ่าน mosh คำสั่งสุดท้ายนี้จะยกเลิกการเชื่อมต่อกับคุณ


34
@artfulrobot เนื่องจากมีโอกาสที่เซสชันแยกออกเป็นของลูกค้า mosh ที่ยังคงอยู่ที่ไหนซักแห่ง ช่วง Mosh เดินเตร่และสามารถอยู่รอดผ่านวงจรหยุดชั่วคราว / ดำเนินการต่อ (เช่น "ไฮเบอร์เนต") ปัญหา mosh ไม่ได้ (และไม่สามารถทำได้อย่างง่ายดาย) การแก้ไขกำลังตรวจพบว่าเครื่องไคลเอนต์รีสตาร์ทโดยไม่ปิดเซสชัน mosh อย่างสง่างาม
binki

7
มีเหตุผลที่จะไม่ทำkillall mosh-serverแทนหรือไม่? โดยเฉพาะอย่างยิ่งตั้งแต่ pidof และ killall เป็นสิ่งเดียวกันจริงๆ
Jordan

6
@Jordan: ในบางระบบ (Solaris ตัวอย่างเช่น), killallไม่ว่าสิ่งที่กล่าว
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

4
หากคุณเชื่อมต่อผ่าน mosh และคุณเรียกใช้killall mosh-serverคุณจะถูกตัดการเชื่อมต่อ
0xcaff

1
@ 0xcaff หากคุณเชื่อมต่อกับ mosh และเรียกใช้kill `pidof mosh-server`คุณจะถูกถอดออกเหมือนกัน
David

26

เพื่อความประหลาดใจของฉันฉันใช้ CRIU ( https://criu.org ) เพื่อตรวจสอบและรีสตาร์ทไคลเอ็นต์ mosh และทำงานได้

ตกตะลึง

ค้นหา PID ของลูกค้า mosh ของคุณ:

$ ps -ef | grep mosh

จากนั้นติดตั้ง CRIU ตามคำแนะนำ

จากนั้นให้ตรวจสอบดังนี้:

$ mkdir จุดตรวจ

$ sudo ./criu dump -D จุดตรวจสอบ -t PID - เชลล์ - งาน

จากนั้นกู้คืน:

$ sudo ./criu restore -D checkpoint --shell-job

และนั่นก็คือ ลูกค้า Mosh ของคุณกลับมาแล้ว

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

ในการแก้ไขปัญหานี้คุณต้องแจ้งให้ mosh หยุดการทำงานและดาวน์โหลดซอร์สโค้ด mosh จากนั้นแก้ไขไฟล์นี้:

ซีดี mosh

เป็นกลุ่ม configure.ac

จากนั้นค้นหาGETTIMEและใส่ความคิดเห็นในบรรทัดนั้น

จากนั้นทำ:

autoreconf # หรือ ./autogen.sh หากคุณเพิ่งโคลนเป็นครั้งแรก

./configure

แต่งหน้า

ทำการติดตั้ง

หลังจากนั้นเซสชันลูกค้า Mosh ที่เป็นจุดตรวจ CRIU ของคุณจะอยู่รอดได้

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


1
อย่าลืมพิมพ์ 'CTRL-L' เพื่อรีเฟรชเอาต์พุตของหน้าจอหลังจากเรียกคืน
Michael Galaxy

6
จากความอยากรู้ที่แท้จริงมีประโยชน์จริง ๆ ในการกู้คืนเซสชันไคลเอ็นต์ mosh ที่ฉันหายไปหรือไม่? ฉันเรียกใช้ tmux บน mosh และสามารถเปิดใช้งาน mosh อีกครั้งบนไคลเอนต์และเชื่อมต่อ tmux อีกครั้ง ... มีประโยชน์ในการทำสิ่งนี้นอกเหนือจากที่ยอดเยี่ยม (ซึ่งจริงๆแล้วมันเป็นจริง!)?
eskhool

1
คำตอบแบบยาว: github.com/mobile-shell/mosh/issues/394คำตอบสั้น ๆ คือใช่: หนึ่งไม่ควรต้องการเซสชัน tmux หาก mosh-server daemon กำลังทำงานอยู่บนเซิร์ฟเวอร์เป้าหมาย มันไม่เพียง แต่จะทำให้ mosh daemons ห้อยต่องแต่ง แต่เป็นการกดแป้นอีกชุดหนึ่งซึ่งเราไม่ควรต้องพิมพ์ในตอนแรก
Michael Galaxy

1
Mosh เป็นตัวสำรอง (ในบางกรณี) สำหรับ SSH ไม่ใช่สำหรับหน้าจอ quoth keithw (ผู้เขียน mosh) บน github
törzsmókus

19

ฉันรู้ว่านี่เป็นโพสต์เก่า แต่มีวิธีแก้ปัญหาง่ายๆนี้ตามที่ Keith Winstein ผู้เขียน mosh แนะนำไว้ที่นี่: https://github.com/mobile-shell/mosh/issues/394

"ก่อนอื่นถ้าคุณต้องการความสามารถในการเชื่อมต่อกับเซสชั่นจากไคลเอนต์หลายคน (หรือหลังจากที่ลูกค้าตาย) คุณควรใช้หน้าจอหรือ tmux Mosh เป็นตัวแทน (ในบางกรณี) สำหรับ SSH ไม่ใช่สำหรับหน้าจอ ผู้ใช้ Mosh หลายคนใช้มันพร้อมกับหน้าจอและชอบแบบนั้น "

สถานการณ์จำลอง: ฉันลงชื่อเข้าใช้เซิร์ฟเวอร์ระยะไกลผ่าน mosh จากนั้นฉันเรียกใช้หน้าจอและมีกระบวนการทำงานในเซสชันของหน้าจอ htop เป็นต้น ฉันขาดการเชื่อมต่อ (แบตเตอรี่แล็ปท็อปหมดการเชื่อมต่อเครือข่าย ฯลฯ ) ฉันเชื่อมต่ออีกครั้งผ่าน mosh และรับข้อความนั้นบนเซิร์ฟเวอร์

Mosh: คุณมีเซสชัน Mosh ที่แยกออกบนเซิร์ฟเวอร์นี้ (mosh [XXXX])

สิ่งที่ฉันต้องทำคือฆ่าเซสชัน mosh ก่อนหน้า

ฆ่า XXXX

และใส่กลับเข้าไปเซสชั่นหน้าจอซึ่งยังคงมีอยู่

หน้าจอ -r

ตอนนี้ htop (หรือกระบวนการใดก็ตามที่ทำงาน) กลับมาเหมือนเดิมโดยไม่มีการขัดจังหวะสิ่งนี้มีประโยชน์อย่างยิ่งสำหรับการรันการอัพเกรดหรือกระบวนการอื่น ๆ ที่จะทำให้เซิร์ฟเวอร์อยู่ในสภาพยุ่งเหยิง ฉันคิดว่าคุณสามารถทำเช่นเดียวกันกับ tmux แม้ว่าฉันจะไม่ได้ลอง ฉันเชื่อว่านี่คือสิ่งที่ Annihilannic และ eskhool แนะนำ


2
นี่คือคำตอบที่ดี ขอบคุณและใช่ฉันยืนยันว่ามันทำงานได้เหมือนกันกับ tmux
laughing_man

10

นอกเหนือจากคำตอบของ Varta ฉันใช้คำสั่งต่อไปนี้เพื่อปิดการเชื่อมต่อ mosh ทั้งหมดยกเว้นคำสั่งปัจจุบัน:

pgrep mosh-server | grep -v $(ps -o ppid --no-headers $$) | xargs kill


ในกรณีที่ไม่มีเซสชัน mosh เก่า xkill จะโยนข้อผิดพลาด ใช้งานได้ดีขึ้นpgrep mosh-server | grep -v $(ps -o ppid --no-headers $$) && xargs kill || echo "no active sessions to kill"
rubo77

4

@varta ชี้ให้เห็นว่าเจ้าของ mosh ต่อต้านการติดตั้งซ้ำจากลูกค้าที่แตกต่างกันด้วยเหตุผลด้านความปลอดภัย ดังนั้นหากลูกค้าของคุณหายไป (เช่นคุณรีสตาร์ทแล็ปท็อป) ตัวเลือกเดียวของคุณคือฆ่าเซสชัน

หากต้องการฆ่าเฉพาะเซสชันที่แยกออกคุณสามารถใช้บรรทัดต่อไปนี้ (ซึ่งฉันมีเป็นชื่อแทนใน.bashrc)

who | grep -v 'via mosh' | grep -oP '(?<=mosh \[)(\d+)(?=\])' | xargs kill

คำสั่งนั้นขึ้นอยู่กับความจริงที่ว่าwhoรายชื่อผู้ใช้ที่เชื่อมต่อรวมถึงเซสชัน mosh เฉพาะเซสชัน mosh ที่แนบเท่านั้นที่มี "ผ่าน mosh" และเซสชัน mosh นั้นมี pid ของพวกเขาในวงเล็บเหลี่ยม ดังนั้นมันจึงพบว่า pids นั้นเป็นเพียงแค่เซสชัน mosh ที่แยกออกมาและส่งผ่านไปเพื่อฆ่าโดยใช้ xargs

นี่คือตัวอย่างwhoผลลัพธ์สำหรับการอ้างอิง:

$ who
theuser    pts/32       2018-01-03 08:39 (17X.XX.248.9 via mosh [193891])
theuser    pts/17       2018-01-03 08:31 (17X.XX.248.9 via mosh [187483])
theuser    pts/21       2018-01-02 18:52 (mosh [205286])
theuser    pts/44       2017-12-21 13:58 (:1001.0)

MOSH_SERVER_SIGNAL_TMOUTทางเลือกคือการใช้ตัวแปรสภาพแวดล้อม mosh เซิร์ฟเวอร์ คุณสามารถตั้งค่าเพื่อสิ่งที่ต้องการใน 300 ของคุณ.bashrcบนฝั่งเซิร์ฟเวอร์ จากนั้นถ้าคุณทำpkill -SIGUSER1 mosh-serverมันจะฆ่าเซิร์ฟเวอร์ mosh ที่ไม่ได้เชื่อมต่อใน 300 วินาทีล่าสุดเท่านั้น (เซิร์ฟเวอร์อื่นจะไม่สนใจ SIGUSER1) ข้อมูลเพิ่มเติมในหน้าคน mosh เซิร์ฟเวอร์ ฉันใช้คำสั่งข้างต้นเพราะเมื่อนามแฝงดูเหมือนฉันจะง่ายขึ้น

หมายเหตุดังที่ @Annihilannic กล่าวถึงหากคุณใช้ tmux / หน้าจอในเซสชัน mosh ของคุณเซสชัน tmux / หน้าจอเหล่านั้นจะยังคงอยู่หลังจากคุณฆ่าเซสชัน mosh ดังนั้นคุณยังสามารถแนบไปกับพวกเขา (ดังนั้นคุณจะไม่สูญเสียมากนักโดยการฆ่าเซสชัน mosh เอง)


3

คำตอบที่นี่โดยอ้างว่าการฆ่าmosh-serverเป็นตัวเลือกเดียวที่ล้าสมัยไปแล้วในขณะที่เราสามารถใช้criuและreptyrกู้คืน

ไม่ต้องพูดถึงว่าทุกวันนี้เราสามารถkill -USR1 mosh-serverฆ่าเซสชันเดี่ยวในวิธีที่สะอาดและปลอดภัยโดยไม่หันไปใช้whoคำสั่งที่ไม่ปลอดภัยหรือคำสั่งที่ยุ่งยากเพื่อหลีกเลี่ยงการฆ่าเซสชันของเราเอง

ถัดcriuจากคำตอบจาก Michael R. Hines มี "น้ำหนักเบา" มากกว่าเล็กน้อยreptyrซึ่งสามารถใช้ในการติดตั้งกระบวนการที่เริ่มต้นใหม่mosh-server(เช่นไม่ใช่mosh-serverตัวเอง) ฉันมักจะใช้

pstree -p <mosh-server PID>

เพื่อแสดงรายการแผนผังกระบวนการภายใต้เซิร์ฟเวอร์ mosh ที่แยกออกแล้ว

reptyr PID

เพื่อติดตั้งใหม่กระบวนการที่ต้องการไปยังสถานีปัจจุบันของฉัน หลังจากทำซ้ำขั้นตอนสำหรับกระบวนการทั้งหมดที่ฉันสนใจฉัน

kill -USR1 <mosh-server PID>

ในขณะที่ฉันดูแลเฉพาะช่วงเวลาฆ่าที่ฉันรู้ว่าเป็นของฉัน (ระบบที่ใช้ร่วมกัน)


ฉันได้รับUnable to attach to pid 10103: Permission denied
rubo77

-1

ใช้คำสั่งpsเพื่อรับรายการภารกิจที่รันอยู่หรือใช้ ps -ef | grep mosh

ฆ่า mosh PID โดยใช้คำสั่งนี้:

kill <pid>

นอกจากนี้หากต้องการปิดการเชื่อมต่อ mosh ทั้งหมดคุณสามารถ:

โปรดทราบว่าหากคุณกำลังเชื่อมต่อผ่าน mosh สิ่งนี้จะยกเลิกการเชื่อมต่อคุณเช่นกัน

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