
Ich bin gerade dabei, ein Shell-Skript zu schreiben, das zeitlich geplant werden kann. Ziel ist es, ein einfaches Backup-Skript für einen Minecraft-Server zu schreiben. Der Server läuft in seinem eigenen, benanntenBildschirm.
Ich gehe davon aus, dass mein Skript etwas in der Art enthält wie
screen -S $(screen_name) -p 0 -X stuff "save-all^M"
der Serverbefehl wird einige Zeit in Anspruch nehmen. Meine Frage ist, wird das Skript sofort fortgesetzt oder wartet es, bis der Befehl im aufgerufenen Bildschirm beendet ist? Wenn es sofort zurückkehrt, wie kann ich darauf warten (in diesem Fall save-all
speichert der Befehl die aktuelle Welt. Der nächste Schritt wäre, die Dateien in einen Sicherungsordner zu kopieren, also möchte ich offensichtlich warten, bis die Welt korrekt gespeichert ist)?
Antwort1
Nein. Der screen -X stuff
Befehl wird sofort zurückgegeben, da ernicht bewusstdass es zunächst aufgefordert wird, einen Befehl auszuführen, und erst recht, wenn dieser Befehl abgeschlossen ist – es fügt lediglich Tastendrücke ein (weshalb Sie das ^M
manuell hinzufügen mussten). Sobald die gefälschte TTY-Eingabe gesendet wurde, kehrt der Befehl zurück und Ihr Skript wird fortgesetzt.
Als Terminalemulator weiß screen im Allgemeinen nicht, was genau in einem bestimmten Terminalfenster geschieht – es gibt nichts, was eine Shell-Eingabeaufforderung (oder eine andere interaktive Konsolen-Eingabeaufforderung) von der regulären Ausgabe unterscheiden würde.
(Das ist nicht grundsätzlich unmöglich – einige Terminalemulatoren erlauben der Shell die Ausgabe von Markierungen wie „output start/end“ und „prompt start/end“, z. B.VSCodefügt eine spezielle Konfiguration in Bash ein, um genau das zu erreichen – erfordert aber die Unterstützung des TerminalemulatorsUndZusammenarbeit von jedem Programm, das eine Eingabeaufforderung anzeigen würde, und weder Screen noch Minecraft tun das derzeit.)
Andererseits könnte es für Ihr Skript einfacher sein, da es nur ein einziges Programm bearbeitet und nur auf einSpezifischEingabeaufforderung angezeigt werden soll, nicht nur irgendeine Eingabeaufforderung im Allgemeinen. Sie könnten dies implementieren, indem Sie eine Schleife haben, die Screen nach dem aktuellen Pufferinhalt abfragt -X hardcopy
, und wenn die letzte Zeile dieses Puffersnichtdie Minecraft-Eingabeaufforderung noch nicht, schlafe 1 Sekunde und wiederhole.
Dies ähnelt der expect
Funktionsweise des Programms: Man kann ein Expect-Skript schreiben, um verschiedene Arten der interaktiven Eingabe zu automatisieren, aber der Kern eines solchen Skripts ist immer ein Satz von expect "this"
und expect "that"
, d. h. man weiß im Voraus, dass ein bestimmter Text eine „Eingabeaufforderung“ ist, und wartet auf diesen Text.
[...]
expect "Password:" { send "$password\r" }
expect ">" { send "enable\r" }
expect "Password:" { send "$enablepwd\r" }
expect "#" { send "show run\r" }
Was andere Minecraft-Verwaltungsskripte tun (wie z. B.dieses Projekt, das kürzlich von Screen auf tmux umgestellt wurde) scheint 1) blind sowohl "save-all" als auch "stop" auf einmal zu senden, 2) zu warten, bis der Server Bot-Befehle verarbeitet, bis er von selbst beendet wird. Das heißt, anstatt auf dieBefehlum abzuschließen, warten sie auf dieErgebnisdieses Befehls.
Wenn Sie warten möchten, bis diespeichernUm fertig zu werden, müssen Sie nicht auf den Befehl „save-all“ warten – Sie können stattdessen inotifywait
warten, bis der Server mit dem Schreiben einer bestimmten Datei fertig ist. Dies kann etwas schwierig sein, richtig zu machen (normalerweise müssten Sie „coproc“ verwenden, um inotifywait zu startenVorden Befehl auszugeben, damit Sie das Ereignis nicht verpassen), aber da das Speichern wahrscheinlich eine Weile dauert, ist eswahrscheinliches ist in Ordnung, es einfach danach zu tun.
echo "waiting..."
inotifywait -q -e close_write /path/to/game
echo "probably done!"
Manche Programme erstellen eine bestimmte Datei absichtlich zuletzt, damit andere Tools auf ihr Erscheinen warten können:
echo "waiting..."
until [ -e /path/to/marker_file ]; do sleep 1; done
echo "marker file showed up"