ayrılmış bir ekrana metin girişi gönderme


44

UnRAID sunucumda bir minecraft sunucusu çalıştırmaya çalışıyorum.

Sunucu kabuğun içinde çalışacak ve daha sonra girişi bekleyerek orada duracaktır. Durdurmak için 'stop' yazmalı ve enter tuşuna basmalıyım, sonra dünyayı kurtaracak ve zarif bir şekilde çıkacağım ve kabuğuma geri döneceğim. Telnetleme yoluyla NAS kutusuna bağladığımda hepsi işe yarar, ancak doğrudan kutunun üzerinde çalıştırmak istiyorum.

Bu daha önce ilk girişim olarak yaşadıklarım:

#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 ve tüm dünya dosyalarının bulunduğu klasör. Bu satırı betiğin içinden yürütürsem, ekran ayarlamıyor gibi görünüyor.

Sunucuyu durdurmak için STOP yazıp 'enter'a basmam gerekiyor. Benim yaklaşımım

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

'Minecraft' ekranına göndermek için metni durdurun ve satır başı gönderin. Ancak, doğrudan komut satırına yazsam bile, bu işe yaramaz. Ama eğer 'screen -r' sunucumu çalıştıran ekrana erişebilirsem, o zaman 'stop' yazıp düzgün bir şekilde kapanıyor.

Telnet içeri girip manuel olarak yaparsam, sunucu iyi çalışıyor, sadece uzak bilgisayarıma bağlanmadan çalıştırmam gerekiyor.


Bu doğru görünüyor . Komut dosyasının içeriği nedir ve onu nasıl çalıştırıyorsunuz? Herhangi bir çıktı veriyor mu? Bunun screenbaşlayamadığını nasıl söylersin ? set -xKomut dosyasının üstüne eklemeyi deneyin ( #!satırın hemen ardından ) ve komut dosyasını çalıştırdığınızda izleme çıktısını raporlayın.
Gilles 'SO- kötülük' dur '28

betiğin tam içeriği budur :) ekran komutu doğrudan girersem çalışır, bu yüzden ana sorunumun durdurma kısmı olduğunu düşünüyorum
richard plumb

“Bu satırı betiğin içinden yürütürsem, bir ekran kurmuş gibi görünmüyor” yazdınız. Öyleyse başlangıç ​​kısmı işe yarıyor mu? Olmazsa, ilk yorumuma bakın.
Gilles 'SO- kötülük' dur '28

Bir unMENU kullanıcı betiği olarak çalıştırmaya çalışıyorum. Bu tam ekran komutuna sahip kullanıcı betiği varsa, hiçbir şey olmuyor. Eğer ekran komutunu telnet penceresine yazarsam, sunucuyu beklediğiniz gibi başlatır. Bu yüzden UNEN kullanıcı komut dosyalarının işlenme biçiminde anlamadığım bir fark olduğunu düşünüyorum.
Richard Plumb

Şimdi bir yerlere geliyoruz. Lütfen sorunuzu unMENU'yu nasıl kullandığınıza ilişkin bilgilerle güncelleyin. Ve iki satır eklemeyi deneyin do #!/bin/bashve set -xscript üst kısmında ve bize komut iz çıktısını gösterir. Bu çıkışın nereye gittiğini bulmak için unMENU belgelerine bakmanız gerekebilir.
Gilles 'SO- kötülük' dur '28

Yanıtlar:


40

Sorunun en azından bir kısmını çözebilirim: neden stopçalışmadığını. Deneysel olarak, bir Ekran oturumunu bağımsız modda ( screen -d -m) başlattığınızda , hiçbir pencere seçilmez, bu nedenle daha sonra gönderilen girdiler screen -X stuffkaybolur. Tuş vuruşlarını 0 ( -p 0) penceresine göndermek istediğinizi açıkça belirtmeniz gerekir . Ne olursa olsun, o Ekran oturumunda başka pencereler oluşturursanız, bu yine de iyi bir fikirdir.

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

(Ekran ^M, Entertuş tarafından gönderilen karakter olan control-M'ye çevrilir .)

Oturumu bir betikten başlatma problemi unMENU ile ilgilidir.


1
güzel, harika çalışıyor (en azından komut satırından sonra mönü adamları dürtecek). Bu epeyce insan atmış gibi görünüyor ve ilk kez somut bir çözüm gördüm. Keşke size oy verebilecek kadar
puanım

Kahretsin! Hatta ekrana takılı bile çalışıyor, yeniden takmadan! Sistemdeki diğer uygulamalardan basit uygulamalara komut göndermenin harika bir yolu var. Teşekkürler! :)
Grzegorz Wierzowiecki

Bu sorunu hiç yaşamadım, muhtemelen ekran oturumumda her zaman birkaç (adlandırılmış) pencere olmasını planlamıştım ve her zaman adıyla pencere seçtim.
Ekevoo

El ile, referans için: -X Belirtilen komutu çalışan ekran oturumuna gönderin. Çalışan birkaç ekran oturumunuz varsa, ekran oturumunu belirlemek için -S seçeneğini kullanabilirsiniz. -D veya -r seçeneğini kullanarak ekrana yalnızca bağlı ya da ayrılmış ekran oturumlarını aramasını söyleyebilirsiniz. Oturum parola korumalıysa bu komutun çalışmadığını unutmayın.
KrisWebDev

3
bu benim için çalışmıyor. Bir ekran yarattım screen -d -m -S hive çalıştırıp screen -S hi -p 0 -X stuff "cd <some_directory>^M"sonuç olarak hiçbir şey almadım ... sadece "cd <some_directory> ^ M" yi bir dizge olarak gönderir ve "^ M" yi enter tuşu olarak yorumlamaz ...
Tanner Strunk

23

İlk önce, yeni satırlara kolayca girildiğine dair bir not:

$()Yapının komut satırından yeni satırları çıkardığı ve böylece çıkış satırlarının diğer programlar için argüman olarak kullanılabildiği bir kafa kafaya . Bu beklenmeyen davranışlara neden olabilir. Bu durumda, özellikle Entertuş vuruşu eşdeğerini göndermeye çalıştığınızı farz ediyorum . Gönderdiğiniz satır başının dönüşü \rçizgili olmazken, ekstra komut kullanmadan bu karaktere girmenin birkaç kolay yolu vardır.

  1. Çift tırnak işaretlerinizin içine normal bir yeni satır yerleştirebilirsiniz.

    screen -S minecraft -X stuff "stop
    "
    
  2. Veya Ctrl+ v Entersırasını kullanarak karakteri bir terminal satırına girebilirsiniz . Bu ^Mterminaldeki gibi görünecek , ancak özel bir yeni satır karakteri.

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

İkincisi, düzensiz ekran davranışı üzerine bir not. ( Gilles tarafından yapılan açıklama ve çözüm )

Ekranda, hiç eklenmemiş bir ekran oturumuna giriş kabul etme ile ilgili bir sorun var. Bunu çalıştırırsanız başarısız olmuş olacak:

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

Ama eğer bunu çalıştırırsan, işe yarayacak:

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

Son olarak, tmuxbunun yerine daha iyi davranış gösteren kullanabilirsiniz screen.

GNU-Screen, yıllardır fiili bir terminal çoklayıcıydı, ancak uzun zamandır geliştirilmekten vazgeçti ve hatalar ve tuhaflıklar giderilemedi. Tmux aktif olarak geliştiriliyor, ekranın dokunamadığı birçok özellik içeriyor ve kutudan çıkardığı davranış oldukça sezgisel. Ayrıca, daha iyi belgelenmiştir. İşte kodunuzu nasıl dönüştüreceğiniz:

# 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"

Eğer ekran -r kullanarak manuel olarak geçersem, ekranı görebilir ve hiçbir metin girilmez. satır başı başarısız olsa bile, yine de yazmaya son vermeliyim. Ama hiçbir şey
richard plumb

Bir satırda -r, ve sonra ekran -X ile bir komut dosyası varsa "X" stop ^ M şeyler o zaman sunucuyu durdurur, ancak aynı zamanda 'hata uknown seçeneği r' ile şikayet ediyor
richard plumb

Burada ekran oturumu oluşturarak, sonra yukarıdaki komutu kullanarak test ettim ve mükemmel çalışıyor. Ekran oturumunuza kullanarak bağlanabiliyor screen -d -RR minecraftmusunuz?
Caleb

evet, bu beni ekrana bağlar. böylece ekran -r .. kilitleniyor, eğer ekran -S minecraft -X şeyler "dur ^ M" sonra el ile ekran -r çalışırsanız, ekranda 'dur' metni var.
Richard Plumb

Benim için çalışıyor. Belki de korkak bir şeyiniz var .screenrcya da bu adla açık olan bir grup boş ekran oturumunuz var ve bu yüzden yanlış olana veri gönderiyorsunuz? screen -list?
Caleb

4

Bu eski yazıyı kazdığım için özür dilerim, ancak bu, benzer bir sorun yaşadığımda bu bilgilere ulaşmam için elimden geleni yapmıştı. Bir bash betiğinde ekran komutlarının nasıl gönderileceği hakkında birçok soru var. Kedi derisi gibi bu yapılabilir, ama ben bu şekilde seviyorum. Bununla say_this işlevini çağırarak herhangi bir komut gönderebilir veya herhangi bir şey söyleyebilirsiniz.

#!/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"
...

Bu ssh ile!

#!/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!"

Güzel ve özlü ... U & L'ye Hoşgeldiniz
eyoung100 16
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.