wysyłanie wprowadzania tekstu na odłączony ekran

44

Próbuję uruchomić serwer Minecraft na moim serwerze unRAID.

Serwer będzie działał w powłoce, a następnie siedział tam i czeka na dane wejściowe. Aby go zatrzymać, muszę wpisać „stop” i nacisnąć Enter, a następnie uratuje świat i z wdziękiem wyjdzie, a ja wrócę do powłoki. To wszystko działa, jeśli uruchomię to przez telnetting do urządzenia NAS, ale chcę uruchomić to bezpośrednio na urządzeniu.

oto, co wcześniej miałem za pierwszą próbą:

#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 jest folderem, w którym mam plik Craftbukkit.jar i wszystkie pliki świata itp. Po wpisaniu bezpośrednio tej linii ekranu ekran zostanie odłączony i serwer zostanie uruchomiony. Jeśli wykonam ten wiersz ze skryptu, wydaje się, że nie ustawiam ekranu

aby zatrzymać serwer, muszę „wpisać” w STOP, a następnie nacisnąć enter. Moje podejście było

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

aby wysłać na ekran „minecrafta” zatrzymanie tekstu i powrót karetki. Ale to nie działa, nawet jeśli wpisuję go bezpośrednio w linii poleceń. Ale jeśli wykonam polecenie „screen -r”, mogę przejść do ekranu z uruchomionym serwerem, a następnie wpisać „stop” i nastąpi prawidłowe zamknięcie.

Serwer działa dobrze, jeśli telnet się i zrobię to ręcznie, wystarczy uruchomić go bez połączenia z komputerem zdalnym.

Richard pion
źródło
To wygląda dobrze . Jaka jest pełna treść skryptu i jak go uruchamiasz? Czy to daje jakieś wyjście? Jak powiedzieć, że screennie udało się uruchomić? Spróbuj dodać set -xna górze skryptu (tuż po #!wierszu) i zgłoś wyniki śledzenia po uruchomieniu skryptu.
Gilles „SO- przestań być zły”
to jest pełna treść skryptu :) polecenie screen działa, jeśli wpisuję go bezpośrednio, więc myślę, że moim głównym problemem jest część stop
richard plumb
Napisałeś „Jeśli wykonam ten wiersz ze skryptu, wydaje się, że nie ustawiam ekranu”. Więc czy część początkowa działa, czy nie? Jeśli nie, zobacz mój pierwszy komentarz.
Gilles „SO- przestań być zły”
Próbuję uruchomić go jako skrypt użytkownika unMENU. Jeśli mam skrypt użytkownika z dokładnie tym poleceniem screen, nic się nie dzieje. Jeśli wpisuję polecenie screen w oknie telnet, uruchamia on serwer na ekranie, jakiego można się spodziewać. Myślę więc, że istnieje pewna różnica, której nie rozumiem w sposobie obsługi skryptów użytkownika UnMENU.
richard pion
Teraz gdzieś się dostaniemy. Zaktualizuj swoje pytanie, podając informacje o tym, jak korzystasz z unMENU. I czy warto dodać dwie linie #!/bin/bashi set -xna początku skryptu, i pokazać nam wyjście śledzenia ze skryptu. Konieczne może być przejrzenie dokumentacji unMENU, aby dowiedzieć się, dokąd trafia ten wynik.
Gilles: „Przestańcie być źli”

Odpowiedzi:

40

Potrafię rozwiązać przynajmniej część problemu: dlaczego ta stopczęść nie działa. Eksperymentalnie po uruchomieniu sesji ekranu w trybie odłączonym ( screen -d -m) nie jest wybierane żadne okno, więc dane przesłane później screen -X stuffsą po prostu tracone. Musisz jawnie określić, że chcesz wysyłać naciśnięcia klawiszy do okna 0 ( -p 0). To i tak jest dobry pomysł, na wypadek, gdyby z jakiegoś powodu zdarzyło Ci się tworzyć inne okna w tej sesji ekranu.

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

(Tłumaczenie ekranu ^Mna control-M, czyli znak wysłany przez Enterklawisz.)

Problem z uruchomieniem sesji ze skryptu jest prawdopodobnie związany z unMENU.

Gilles „SO- przestań być zły”
źródło
1
piękny, działa świetnie (przynajmniej z wiersza poleceń, później wyśmiewa niemiłych facetów). Wydaje się, że rzuciło to sporo osób i po raz pierwszy widziałem konkretne rozwiązanie. Chciałbym tylko mieć wystarczającą liczbę punktów, aby zagłosować: D
richard plumb
Cholera ** Działa nawet ekran jest już podłączony, bez ponownego podłączania! Jaki jest świetny sposób wysyłania poleceń do prostych aplikacji z innych aplikacji w systemie. Dzięki! :)
Grzegorz Wierzowiecki
Nigdy nie miałem tego problemu, prawdopodobnie dlatego, że zawsze planowałem mieć kilka (nazwanych) okien w mojej sesji ekranowej i zawsze wybieram okno po nazwie.
Ekevoo
Podręcznik, w celach informacyjnych: -X Wyślij określone polecenie do uruchomionej sesji ekranu. Możesz użyć opcji -S, aby określić sesję ekranu, jeśli masz uruchomionych kilka sesji ekranu. Możesz użyć opcji -d lub -r, aby powiedzieć screenowi, aby szukał tylko sesji dołączonych lub odłączonych. Pamiętaj, że to polecenie nie działa, jeśli sesja jest chroniona hasłem.
KrisWebDev
3
to nie działa dla mnie. Utworzyłem ekran, screen -d -m -S hia następnie uruchomiłem screen -S hi -p 0 -X stuff "cd <some_directory>^M"i nic nie otrzymałem w wyniku ... wysyła po prostu „cd <katalog_>> M” jako ciąg znaków i nie interpretuje „^ M” jako klawisza Enter ...
Tanner Strunk
23

Po pierwsze, uwaga na temat łatwego wprowadzania nowych linii:

Tylko jedna głowa do góry, że $()konstrukcja usuwa nowe wiersze z wyjścia polecenia, dzięki czemu wiersze wyjściowe mogą być użyte jako argumenty dla innych programów. Może to spowodować nieoczekiwane zachowanie. W tym przypadku zakładam, że konkretnie próbujesz wysłać odpowiednik Enternaciśnięcia klawisza. Chociaż zwrot karetki, który wysyłasz \r, nie zostanie rozłożony, istnieje kilka łatwiejszych sposobów na wejście do tej postaci bez potrzeby dodatkowego polecenia.

  1. W podwójnych cudzysłowach możesz umieścić regularny znak nowej linii

    screen -S minecraft -X stuff "stop
    "
    
  2. Lub możesz wprowadzić znak w linii terminalu, używając sekwencji Ctrl+ v Enter. Będzie to wyglądać jak ^Mw terminalu, ale jest to specjalny znak nowej linii.

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

Po drugie, uwaga na temat błędnego zachowania ekranu. ( Wyjaśnienie i rozwiązanie Gilles )

Wystąpił problem z akceptacją danych wejściowych do sesji ekranu, która nigdy nie została dołączona. Jeśli uruchomisz to, to się nie powiedzie:

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

Ale jeśli to uruchomisz, zadziała:

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

Na koniec możesz użyć znacznie lepiej zachowanego tmuxzamiast screen.

GNU-Screen jest de facto multiplekserem terminali od wielu lat, ale już dawno przestał być rozwijany, a błędy i dziwactwa się nie naprawiają. Tmux jest w fazie rozwoju, zawiera wiele funkcji, których ekran nie może dotknąć, a jego zachowanie po wyjęciu z pudełka jest raczej bardziej intuicyjne. Ponadto jest lepiej udokumentowany. Oto jak przekonwertowałbyś swój kod:

# 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
źródło
jeśli ręcznie przełączę za pomocą screen -r, zobaczę ekran i nie zostanie wprowadzony żaden tekst. nawet jeśli powrót karetki nie powiódł się, nadal powinienem wpisać „stop”. Ale nic
Richard Plumb
jeśli mam skrypt z screen -r w jednym wierszu, a następnie screen -X wpisuje „stop ^ M”, to zatrzymuje serwer, ale także narzeka na „błąd uknown Option r”
Richard Plumb
Testowałem tutaj, tworząc sesję ekranową, a następnie używając powyższego polecenia i działa idealnie. Czy jesteś w stanie połączyć się z sesją ekranową za pomocą screen -d -RR minecraft?
Caleb
tak, to łączy mnie z ekranem. podobnie jak screen -r .. zawiesił się, jeśli spróbuję screen -S minecraft -X rzeczy „stop ^ M”, a następnie ręcznie screen -r, na ekranie pojawia się tekst „stop”.
richard pion
Pracuje dla mnie. Być może masz w sobie coś funky .screenrclub masz otwartą serię nieefektywnych sesji ekranowych o tej nazwie, więc wysyłasz dane do niewłaściwej? screen -list?
Caleb
4

Przepraszam za wykopanie tego starego postu, ale pomogłoby mi to w moich staraniach, gdyby te informacje były dostępne w czasie, gdy miałem podobny problem. Istnieje wiele pytań dotyczących wysyłania poleceń ekranowych w skrypcie bash. Tak jak w przypadku skórowania kota, można to zrobić, ale podoba mi się to w ten sposób. Dzięki temu możesz wysłać dowolne polecenie lub powiedzieć cokolwiek, wywołując funkcję 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"
...

To jest z 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
źródło
Ładne i zwięzłe ... Witamy w U&L
eyoung100