mengirim input teks ke layar terpisah

44

Saya mencoba menjalankan server minecraft di server unRAID saya.

Server akan berjalan di shell, dan kemudian duduk di sana menunggu input. Untuk menghentikannya, saya harus mengetik 'berhenti' dan tekan enter, dan kemudian itu akan menyelamatkan dunia dan keluar dengan anggun, dan saya kembali ke shell. Itu semua berfungsi jika saya menjalankannya melalui telnetting ke dalam kotak NAS, tetapi saya ingin menjalankannya langsung di kotak itu.

inilah yang sebelumnya saya lakukan sebagai upaya pertama:

#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 adalah folder di mana saya memiliki Craftbukkit.jar dan semua file dunia, dll. Jika saya mengetikkan garis layar itu secara langsung, layar pengaturannya terlepas dan server diluncurkan. Jika saya mengeksekusi baris itu dari dalam skrip, sepertinya ia tidak mengatur layar

untuk menghentikan server, saya perlu 'mengetik' di STOP dan kemudian tekan enter. Pendekatan saya adalah

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

untuk mengirim ke layar 'minecraft' berhenti teks dan carriage return. Tapi itu tidak berhasil, bahkan jika saya mengetiknya langsung ke baris perintah. Tetapi jika saya 'layar -r' saya bisa mendapatkan layar dengan server berjalan, kemudian ketik 'berhenti' dan dimatikan dengan benar.

Server berjalan dengan baik jika saya telnet dan melakukannya secara manual, hanya perlu menjalankannya tanpa terhubung dari komputer jarak jauh saya.

richard plumb
sumber
Ini terlihat benar . Apa isi lengkap skrip dan bagaimana Anda menjalankannya? Apakah ini menghasilkan output? Bagaimana Anda tahu itu screengagal memulai? Coba tambahkan set -xdi bagian atas skrip (tepat setelah #!baris) dan laporkan hasil penelusuran ketika Anda menjalankan skrip.
Gilles 'SANGAT berhenti menjadi jahat'
itu adalah isi penuh dari skrip :) perintah layar berfungsi jika saya mengetikkannya secara langsung, jadi saya pikir masalah utama saya adalah bagian penghentian
richard plumb
Anda menulis "Jika saya mengeksekusi baris itu dari dalam skrip, sepertinya ia tidak mengatur layar". Jadi apakah bagian awal bekerja atau tidak? Jika tidak, lihat komentar pertama saya.
Gilles 'SANGAT berhenti menjadi jahat'
Saya mencoba menjalankannya sebagai skrip pengguna unMENU. Jika saya memiliki skrip pengguna dengan perintah layar yang tepat, tidak ada yang terjadi. Jika saya mengetik perintah layar ke jendela telnet, itu meluncurkan server di layar seperti yang Anda harapkan. Jadi saya pikir ada beberapa perbedaan yang saya tidak mengerti dalam hal penanganan skrip pengguna unMENU.
richard montok
Sekarang kita pergi ke suatu tempat. Harap perbarui pertanyaan Anda dengan informasi tentang bagaimana Anda menggunakan unMENU. Dan cobalah menambahkan dua baris #!/bin/bashdan set -xdi bagian atas skrip, dan tunjukkan kami jejak hasil dari skrip. Anda mungkin perlu mencari di dokumentasi unMENU untuk mengetahui ke mana perginya output itu.
Gilles 'SANGAT berhenti menjadi jahat'

Jawaban:

40

Saya dapat memecahkan setidaknya sebagian dari masalah: mengapa stopbagian itu tidak berfungsi. Secara eksperimental, ketika Anda memulai sesi Layar dalam mode terlepas ( screen -d -m), tidak ada jendela yang dipilih, sehingga input yang dikirim nanti screen -X stuffhilang begitu saja. Anda harus secara eksplisit menentukan bahwa Anda ingin mengirim penekanan tombol ke jendela 0 ( -p 0). Ini adalah ide yang baik, jika Anda kebetulan membuat windows lain di sesi Layar itu untuk alasan apa pun.

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

(Layar menerjemahkan ^Mke kontrol-M yang merupakan karakter yang dikirim oleh Entertombol.)

Masalah dengan memulai sesi dari skrip kemungkinan terkait dengan unMENU.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
beautiful, works great (setidaknya dari command line, akan menyodok orang-orang unmenu nanti). Ini tampaknya telah melemparkan beberapa orang dan ini pertama kalinya saya melihat solusi konkret. Saya hanya berharap saya punya cukup poin untuk memilih Anda: D
richard menyelimuti
Sial ** t! Ini berfungsi bahkan layar sudah terpasang, tanpa memasang kembali! Apa cara terbaik untuk mengirim perintah ke aplikasi sederhana dari aplikasi lain di sistem. Terima kasih! :)
Grzegorz Wierzowiecki
Saya tidak pernah memiliki masalah ini, mungkin karena saya selalu berencana untuk memiliki beberapa (bernama) jendela di sesi layar saya, dan saya selalu memilih jendela berdasarkan nama.
Ekevoo
Manual, untuk referensi: -X Kirim perintah yang ditentukan ke sesi layar berjalan. Anda dapat menggunakan opsi -S untuk menentukan sesi layar jika Anda menjalankan beberapa sesi layar. Anda dapat menggunakan opsi -d atau -r untuk memberi tahu layar agar hanya mencari sesi layar yang dilampirkan atau dilepaskan. Perhatikan bahwa perintah ini tidak berfungsi jika sesi dilindungi kata sandi.
KrisWebDev
3
ini tidak bekerja untuk saya. Saya telah membuat layar dengan screen -d -m -S hidan kemudian menjalankan screen -S hi -p 0 -X stuff "cd <some_directory>^M"dan tidak mendapatkan apa-apa sebagai hasilnya ... hanya mengirimkan "cd <some_directory> ^ M" sebagai string dan tidak mengartikan "^ M" sebagai masukkan kunci ...
Tanner Strunk
23

Pertama, catatan tentang cara memasukkan baris dengan mudah:

Hanya kepala bahwa $()konstruk strip baris baru dari output perintah sehingga garis output dapat digunakan sebagai argumen untuk program lain. Ini dapat menyebabkan perilaku yang tidak terduga. Dalam hal ini saya menganggap Anda secara khusus mencoba mengirim yang setara dengan Enterkeystroke. Meskipun carriage return yang Anda kirim \rtidak akan bergaris, ada beberapa cara yang lebih mudah untuk memasukkan karakter itu tanpa perlu perintah tambahan.

  1. Anda dapat menempatkan baris baru reguler di dalam tanda kutip ganda Anda

    screen -S minecraft -X stuff "stop
    "
    
  2. Atau Anda dapat memasukkan karakter di baris terminal menggunakan urutan Ctrl+ v Enter. Ini akan terlihat seperti ^Mdi terminal, tetapi ini merupakan karakter baris baru khusus.

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

Kedua, Catatan tentang perilaku layar yang tidak menentu. ( Penjelasan dan solusi oleh Gilles )

Layar memiliki masalah dengan menerima input ke sesi layar yang belum pernah dilampirkan. Jika Anda menjalankan ini, itu akan gagal:

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

Tetapi jika Anda menjalankan ini akan berhasil:

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

Terakhir, Anda bisa menggunakan jauh lebih baik berperilaku tmuxbukan screen.

GNU-Screen telah menjadi terminal multiplexer de-facto selama bertahun-tahun, tetapi telah lama berhenti dikembangkan dan bug dan keanehan tidak diperbaiki. Tmux sedang dalam pengembangan aktif, mencakup banyak fitur yang tidak dapat disentuh layar, dan perilakunya di luar kotak agak lebih intuitif. Juga, lebih baik didokumentasikan. Inilah cara Anda mengonversi kode Anda:

# 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"
Caleb
sumber
jika saya beralih menggunakan layar -r secara manual, saya bisa melihat layar, dan tidak ada teks yang dimasukkan sama sekali. bahkan jika kembalinya kereta gagal, saya masih harus 'berhenti' mengetik. Tapi tidak ada
richard menyelinap
jika saya memiliki skrip dengan layar -r pada satu baris, dan kemudian layar -X hal-hal "berhenti ^ M" maka itu menghentikan server, tetapi juga mengeluh dengan 'opsi kesalahan uknown r'
richard plumb
Saya diuji di sini dengan membuat sesi layar, kemudian menggunakan perintah di atas dan itu berfungsi dengan baik. Apakah Anda dapat terhubung ke sesi layar menggunakan screen -d -RR minecraft?
Caleb
ya, itu menghubungkan saya ke layar. begitu juga layar -r .. tunggu, jika saya mencoba layar -S minecraft -X stuff "stop ^ M" maka secara manual layar -r, ada teks 'berhenti' di layar.
richard montok
Bekerja untukku. Mungkin Anda memiliki sesuatu yang funky di Anda .screenrcatau Anda memiliki banyak sesi layar defunkt terbuka dengan nama itu dan jadi Anda mengirim data ke yang salah? screen -list?
Caleb
4

Saya minta maaf karena menggali posting lama ini, tetapi ini akan membantu saya dalam usaha saya seandainya informasi ini tersedia pada saat saya memiliki masalah yang sama. Ada banyak pertanyaan tentang cara mengirim perintah layar dalam skrip bash. Seperti halnya menguliti kucing, ini mungkin dilakukan, tetapi saya suka cara ini. Dengan ini, Anda dapat mengirim perintah atau mengatakan apa pun hanya dengan memanggil fungsi 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"
...

Ini dengan 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!"
fuzzyfreak
sumber
Bagus dan Ringkas ... Selamat datang di U&L
eyoung100