ส่งข้อความไปยังหน้าจอเดี่ยว


44

ฉันพยายามเรียกใช้เซิร์ฟเวอร์ minecraft บนเซิร์ฟเวอร์ unRAID ของฉัน

เซิร์ฟเวอร์จะทำงานในเปลือกแล้วนั่งรอการป้อนข้อมูล ในการหยุดมันฉันต้องพิมพ์ 'หยุด' และกด Enter จากนั้นมันจะช่วยโลกและออกอย่างสง่างามและฉันกลับมาที่เปลือก ทั้งหมดนี้ใช้งานได้หากฉันเรียกใช้ผ่าน telnetting ในช่อง NAS แต่ฉันต้องการเรียกใช้โดยตรงบนกล่อง

นี่คือสิ่งที่ฉันเคยลองเป็นครั้งแรก:

#define USER_SCRIPT_LABEL Start Minecraft server
#define USER_SCRIPT_DESCR Start minecraft server. needs sde2 mounted first
cd /mnt/disk/sde2/MCunraid
screen -d -m -S minecraft /usr/lib/java/bin/java -Xincgc -Xmx1024M -jar CraftBukkit.jar

MCunraid เป็นโฟลเดอร์ที่ฉันมี Craftbukkit.jar และไฟล์ทั้งหมดของโลกเป็นต้นหากฉันพิมพ์บรรทัดหน้าจอนั้นลงในหน้าจอโดยตรงหน้าจอจะทำการติดตั้งและเซิร์ฟเวอร์จะเปิดขึ้น หากฉันดำเนินการบรรทัดนั้นจากภายในสคริปต์ดูเหมือนจะไม่ได้ตั้งค่าหน้าจอ

สำหรับการหยุดเซิร์ฟเวอร์ฉันต้อง 'พิมพ์' ใน STOP แล้วกด Enter แนวทางของฉันคือ

screen -S minecraft -X stuff "stop $(echo -ne '\r')"

เพื่อส่งไปยังหน้าจอ 'minecraft' ข้อความจะหยุดและคืนค่าขนส่ง แต่นั่นไม่ได้ผลแม้ว่าฉันจะพิมพ์โดยตรงไปยังบรรทัดคำสั่ง แต่ถ้าฉัน 'หน้าจอ -r' ฉันสามารถไปที่หน้าจอโดยที่เซิร์ฟเวอร์ทำงานอยู่ให้พิมพ์ 'หยุด' และปิดลงอย่างถูกต้อง

เซิร์ฟเวอร์ทำงานได้ดีถ้าฉัน telnet และทำด้วยตนเองเพียงแค่ต้องเรียกใช้โดยไม่ต้องเชื่อมต่อจากคอมพิวเตอร์ระยะไกลของฉัน


ลักษณะนี้ได้ เนื้อหาทั้งหมดของสคริปต์คืออะไรและคุณใช้งานอย่างไร มันผลิตผลผลิตใด ๆ คุณจะบอกได้อย่างไรว่าscreenการเริ่มต้นล้มเหลว ลองเพิ่มset -xที่ด้านบนสุดของสคริปต์ (หลัง#!บรรทัด) และรายงานผลลัพธ์การติดตามเมื่อคุณเรียกใช้สคริปต์
Gilles 'หยุดความชั่วร้าย' ใน

นั่นคือเนื้อหาทั้งหมดของสคริปต์ :) คำสั่งหน้าจอทำงานถ้าฉันพิมพ์โดยตรงดังนั้นฉันคิดว่าปัญหาหลักของฉันคือส่วนหยุด
ริชาร์ดดด

คุณเขียน“ ถ้าฉันเรียกใช้บรรทัดนั้นจากภายในสคริปต์ดูเหมือนว่าจะไม่ได้ตั้งค่าหน้าจอ” ส่วนเริ่มต้นทำงานได้หรือไม่? ถ้าไม่เห็นความคิดเห็นแรกของฉัน
Gilles 'หยุดความชั่วร้าย' ใน

ฉันพยายามเรียกใช้เป็นสคริปต์ผู้ใช้ unMENU หากฉันมีสคริปต์ผู้ใช้ที่มีคำสั่งหน้าจอที่แน่นอนจะไม่มีอะไรเกิดขึ้น หากฉันพิมพ์คำสั่งหน้าจอลงในหน้าต่างเทลเน็ตมันจะเปิดเซิร์ฟเวอร์ในหน้าจอตามที่คุณคาดหวัง ดังนั้นฉันคิดว่ามีความแตกต่างบางอย่างที่ฉันไม่เข้าใจในวิธีการจัดการสคริปต์ผู้ใช้ unMENU
ริชาร์ดดด

ตอนนี้เรากำลังเดินทางอยู่ที่ไหนซักแห่ง โปรดอัปเดตคำถามของคุณพร้อมข้อมูลเกี่ยวกับวิธีการใช้ unMENU และลองเพิ่มสองบรรทัด#!/bin/bashและset -xที่ด้านบนสุดของสคริปต์และแสดงผลลัพธ์การติดตามจากสคริปต์ คุณอาจต้องดูในเอกสาร unMENU เพื่อค้นหาว่าเอาต์พุตนั้นไปที่ใด
Gilles 'หยุดความชั่วร้าย' ใน

คำตอบ:


40

ฉันสามารถแก้ปัญหาได้อย่างน้อยส่วนหนึ่ง: ทำไมstopส่วนไม่ทำงาน ทดลองเมื่อคุณเริ่มเซสชันหน้าจอในโหมดแยกออก ( screen -d -m) จะไม่มีหน้าต่างใดถูกเลือกดังนั้นอินพุตที่ส่งในภายหลังด้วยscreen -X stuffจะหายไป คุณต้องระบุอย่างชัดเจนว่าคุณต้องการส่งการกดแป้นไปที่หน้าต่าง 0 ( -p 0) นี่เป็นความคิดที่ดีอยู่แล้วในกรณีที่คุณเกิดขึ้นเพื่อสร้างหน้าต่างอื่น ๆ ในเซสชันหน้าจอนั้นด้วยเหตุผลใดก็ตาม

screen -S minecraft -p 0 -X stuff "stop^M"

(Screen translate ^Mto control-M ซึ่งเป็นตัวละครที่ส่งโดยEnterกุญแจ)

ปัญหาเกี่ยวกับการเริ่มเซสชันจากสคริปต์นั้นอาจเกี่ยวข้องกับ unMENU


1
สวยงามใช้งานได้ดี (อย่างน้อยจากบรรทัดคำสั่งจะกระตุ้นพวกผู้ชายที่ไม่ได้ใช้ในภายหลัง) ดูเหมือนว่าจะมีคนมาค่อนข้างน้อยและเป็นครั้งแรกที่ฉันได้เห็นวิธีแก้ปัญหาที่เป็นรูปธรรม ฉันแค่หวังว่าฉันจะมีคะแนนมากพอที่จะให้คะแนนคุณ: D
richard plumb

ประณาม s ** t! มันใช้งานได้แม้กระทั่งติดตั้งหน้าจอไว้โดยไม่ต้องติดตั้งซ้ำ! เป็นวิธีที่ยอดเยี่ยมในการส่งคำสั่งไปยังแอพง่าย ๆ จากแอพอื่น ๆ ในระบบ ขอบคุณ! :)
Grzegorz Wierzowiecki

ฉันไม่เคยมีปัญหานี้อาจเป็นเพราะฉันมักจะวางแผนที่จะมีหน้าต่าง (ชื่อ) หลายหน้าต่างในเซสชันหน้าจอของฉันและฉันมักจะเลือกหน้าต่างตามชื่อ
Ekevoo

คู่มือ, สำหรับการอ้างอิง: -X ส่งคำสั่งที่ระบุไปยังเซสชันหน้าจอที่กำลังรัน คุณอาจใช้ตัวเลือก -S เพื่อระบุเซสชันหน้าจอหากคุณมีเซสชันเซสชันหลายหน้าจอทำงานอยู่ คุณสามารถใช้ตัวเลือก -d หรือ -r เพื่อบอกหน้าจอให้ค้นหาเฉพาะเซสชันหน้าจอที่แนบหรือแยกออก โปรดทราบว่าคำสั่งนี้จะไม่ทำงานหากเซสชันได้รับการป้องกันด้วยรหัสผ่าน
KrisWebDev

3
มันไม่ได้ผลสำหรับฉัน ฉันสร้างหน้าจอด้วยscreen -d -m -S hiแล้วเรียกใช้แล้วscreen -S hi -p 0 -X stuff "cd <some_directory>^M"ไม่ได้ผลอะไรเลย ... มันแค่ส่ง "cd <some_directory> ^ M" เป็นสตริงและไม่แปลว่า "^ M" เป็นคีย์ป้อน ...
Tanner Strunk

23

ก่อนอื่นให้ทราบเกี่ยวกับการป้อนบรรทัดใหม่ได้อย่างง่ายดาย:

เพียงแค่หัวขึ้นว่า$()โครงสร้างสร้างขึ้นบรรทัดใหม่จากเอาต์พุตของคำสั่งเพื่อให้บรรทัดเอาต์พุตสามารถใช้เป็นอาร์กิวเมนต์สำหรับโปรแกรมอื่น ๆ สิ่งนี้อาจทำให้เกิดพฤติกรรมที่ไม่คาดคิด ในกรณีนี้ฉันคิดว่าคุณกำลังพยายามส่งการEnterกดแป้นพิมพ์โดยเฉพาะ ในขณะที่\rการขึ้นบรรทัดใหม่ที่คุณส่งมาจะไม่ได้รับการสไทรพ์มีหลายวิธีที่ง่ายกว่าในการป้อนอักขระนั้นโดยไม่จำเป็นต้องใช้คำสั่งพิเศษ

  1. คุณสามารถวางบรรทัดใหม่เป็นประจำในเครื่องหมายคำพูดคู่ของคุณ

    screen -S minecraft -X stuff "stop
    "
    
  2. หรือคุณสามารถป้อนอักขระในบรรทัดเทอร์มินัลโดยใช้ลำดับCtrl+ v Enterสิ่งนี้จะมีลักษณะเหมือน^Mในเทอร์มินัล แต่เป็นอักขระขึ้นบรรทัดใหม่พิเศษ

    screen -S minecraft -X stuff "stop^M"
    

ประการที่สองทราบเกี่ยวกับพฤติกรรมหน้าจอที่ผิดปกติ ( คำอธิบายและการแก้ปัญหาโดย Gilles )

หน้าจอมีปัญหากับการยอมรับอินพุตไปยังเซสชันหน้าจอที่ไม่เคยแนบมาด้วย หากคุณเรียกใช้งานสิ่งนี้จะล้มเหลว:

screen -d -m -S minecraft zsh
screen -S minecraft -X stuff "stop^M"
screen -r minecraft

แต่ถ้าคุณใช้งานมันจะทำงาน:

screen -d -m -S minecraft zsh
screen -r minecraft (then disconnect with Ctrl-a-d)
screen -S minecraft -X stuff "stop^M"
screen -r minecraft

สุดท้ายคุณสามารถใช้ความประพฤติดีมากแทนtmuxscreen

GNU-Screen นั้นเป็นเครื่องมัลติเพล็กเซอร์แบบเดอพฤตินัยเป็นเวลาหลายปี แต่มันหยุดพัฒนามานานและข้อผิดพลาดและนิสัยใจคอไม่ได้รับการแก้ไข Tmux อยู่ภายใต้การพัฒนาที่ใช้งานอยู่รวมถึงคุณสมบัติต่าง ๆ ที่หน้าจอไม่สามารถสัมผัสได้และพฤติกรรมของมันออกมานอกกรอบค่อนข้างง่ายกว่า นอกจากนี้ยังมีเอกสารที่ดีกว่า นี่คือวิธีที่คุณจะแปลงรหัสของคุณ:

# Start new detached tmux session with a named window pane running the java app
tmux new-session -d -n minecraft /usr/lib/java/bin/java [args]

# Send it keys to stop the mincraft server
tmux send-keys -t minecraft "stop^M"

หากฉันสลับไปมาโดยใช้หน้าจอ -r ด้วยตนเองฉันสามารถเห็นหน้าจอและไม่มีข้อความป้อนเลย แม้ว่าการรับคืนรถจะล้มเหลวฉันก็ควรพิมพ์ 'หยุด' แต่ไม่มีอะไร
ริชาร์ดดดดด

ถ้าฉันมีสคริปต์ที่มีหน้าจอ -r ในบรรทัดเดียวและจากนั้นหน้าจอ - สิ่ง X "หยุด ^ M" แล้วมันจะหยุดเซิร์ฟเวอร์ แต่ยังบ่นกับ 'ข้อผิดพลาดตัวเลือก uknown r'
ริชาร์ดดิ่ง

ฉันทดสอบที่นี่โดยการสร้างหน้าจอเซสชันจากนั้นใช้คำสั่งด้านบนและทำงานได้อย่างสมบูรณ์ คุณสามารถเชื่อมต่อกับเซสชันหน้าจอของคุณโดยใช้screen -d -RR minecraftหรือไม่?
Caleb

ใช่นั่นเชื่อมโยงฉันกับหน้าจอ ถ้าฉันลองใช้ screen -S minecraft -X stuff "stop ^ M" จากนั้นหน้าจอด้วยตนเอง -r มีข้อความ 'หยุด' ในหน้าจอ
ริชาร์ดดด

ใช้งานได้สำหรับฉัน บางทีคุณอาจมีบางสิ่งที่ขี้ขลาดในตัวคุณ.screenrcหรือคุณมีช่วงหน้าจอเริ่มต้นที่มีการแยกส่วนของ defunkt โดยใช้ชื่อนั้นและคุณกำลังส่งข้อมูลไปยังตำแหน่งที่ไม่ถูกต้องหรือไม่ screen -list?
Caleb

4

ฉันขอโทษสำหรับการขุดโพสต์เก่านี้ แต่สิ่งนี้จะช่วยฉันในความพยายามของฉันหากข้อมูลนี้มีให้ในเวลาที่ฉันมีปัญหาที่คล้ายกัน มีคำถามมากมายเกี่ยวกับวิธีส่งคำสั่งหน้าจอในสคริปต์ทุบตี การทำสกินแคทเช่นนี้อาจทำได้ แต่ฉันชอบวิธีนี้ ด้วยวิธีนี้คุณสามารถส่งคำสั่งใด ๆ หรือพูดอะไรก็ได้เพียงแค่เรียกใช้ฟังก์ชัน say_this

#!/bin/bash

say_this()
{
    screen -S minecraft -p 0 -X stuff "$1^M"
}

say_this "say Saving world"
say_this "save-off"
say_this "save-all"
...

นี่คือกับ ssh!

#!/bin/bash

say_this()
{
    # Dont forget to set NAME or whatever
    ssh -p 8989 192.168.1.101 screen -S $NAME -p 0 -X stuff \"$1^M\"
}

say_this "say test"
say_this "say !@#$%^&*()<>?This string will work!"

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