Ich kann zumindest einen Teil des Problems lösen:Warum der stop
Teil funktioniert nicht. Wenn Sie eine Screen-Sitzung im getrennten Modus starten (screen -d -m
), kein Fenster ausgewählt, also Eingabe später mit screen -X stuff
gesendet ist einfach verloren. Sie müssen explizit angeben, dass Sie die Tastenanschläge an Fenster 0 senden möchten (-p 0
). Dies ist sowieso eine gute Idee, falls Sie aus irgendeinem Grund andere Fenster in dieser Screen-Sitzung erstellen.
screen -S minecraft -p 0 -X stuff "stop^M"
(Bildschirmübersetzung ^M
an control-M, das ist das Zeichen, das von Enter gesendet wird Schlüssel.)
Das Problem beim Starten der Sitzung aus einem Skript hängt wahrscheinlich mit unMENU zusammen.
Zuerst ein Hinweis zur einfachen Eingabe von Zeilenumbrüchen:
Nur eine Warnung, dass die $()
construct entfernt Zeilenumbrüche aus der Ausgabe des Befehls, sodass die Ausgabezeilen als Argumente für andere Programme verwendet werden können. Dies kann zu unerwartetem Verhalten führen. In diesem Fall gehe ich davon aus, dass Sie ausdrücklich versuchen, das Äquivalent von Enter zu senden Tastenanschlag. Beim Carriage Return senden Sie mit \r
nicht gestreift wird, gibt es mehrere einfachere Möglichkeiten, dieses Zeichen einzugeben, ohne dass der zusätzliche Befehl erforderlich ist.
-
Sie können einen regulären Zeilenumbruch in Ihre doppelten Anführungszeichen setzen
screen -S minecraft -X stuff "stop "
-
Oder Sie geben das Zeichen mit Strg in eine Terminalzeile ein +v Eingabe Reihenfolge. Das sieht in etwa so aus:
^M
im Terminal, aber es ist ein spezielles Newline-Zeichen.screen -S minecraft -X stuff "stop^M"
Zweitens eine Anmerkung zum fehlerhaften Bildschirmverhalten. (Erklärung und Lösung von Gilles)
Screen hat ein Problem mit dem Akzeptieren von Eingaben für eine Bildschirmsitzung, die noch nie angehängt wurde. Wenn Sie dies ausführen, ist es fehlgeschlagen:
screen -d -m -S minecraft zsh
screen -S minecraft -X stuff "stop^M"
screen -r minecraft
Aber wenn Sie das ausführen, wird es funktionieren:
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
Zu guter Letzt könnten Sie den viel besser erzogenen tmux
verwenden statt screen
.
GNU-Screen war de-facto Terminal-Multiplexer seit vielen Jahren, aber es wird schon lange nicht mehr weiterentwickelt und Bugs und Macken werden nicht behoben. Tmux befindet sich in aktiver Entwicklung, enthält viele Funktionen, die der Bildschirm nicht berühren kann, und sein Verhalten ist von Haus aus eher intuitiver. Außerdem ist es besser dokumentiert. So konvertieren Sie Ihren Code:
# 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"
Ich entschuldige mich für das Ausgraben dieses alten Beitrags, aber dies hätte mir bei meinen Bemühungen geholfen, wenn diese Informationen zu dem Zeitpunkt verfügbar gewesen wären, als ich ein ähnliches Problem hatte. Es gibt viele Fragen zum Senden von Bildschirmbefehlen in einem Bash-Skript. Wie beim Katzenhäuten kann dies getan werden, aber ich mag diese Art und Weise. Damit können Sie jeden Befehl senden oder alles sagen, indem Sie einfach die Funktion say_this aufrufen.
#!/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"
...
Das geht mit 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 [email protected]#$%^&*()<>?This string will work!"