システムサービスを制御するために画面を使用する方法は?

システムサービスを制御するために画面を使用する方法は?

私のMinecraftサーバーを実行するためにシステムサービスを設定しました。これで、サーバーがクラッシュしたときに起動スクリプトを繰り返す必要があります。これは私のコードです。

#!/bin/bash

while true; do
    cd /home/mcserver/Spigot
    echo Starting Spigot...
    echo 600 > ./restart-info
    java -jar spigot.jar
    echo Server has stopped or crashed, starting again in 5 minutes...
    sleep 300
done

spigot.jar実際にを使用して出力を表示できますが、を使用してsystemctl status spigotサーバーコンソールを制御したいと思いますscreen

私がこれをしようとしたとき:

screen -S "Spigot" java -jar spigot.jar

エラーが発生しますMust be connected to a terminal。このコマンドはスクリプトではなく端末でのみ機能しますscreen -r

この画面エラーを「バイパス」する方法はありますか?script /dev/null画面コマンドの前に配置してみました。 -dと-mと一緒にscreenを使用したくありません。なぜなら、このコマンドはバックグラウンドで実行され、スクリプトは私のサーバーを再起動し続けるからです。

答え1

偶然に見つけたと思うこのブログ投稿SSH または Putty セッションを閉じるときにscreenMinecraft サーバーが停止する問題を解決するために使用されます。$ java -jar spigot.jarこの方法は必須ではありませんが、Minecraftサーバーを実行する方法に対する標準的な回答になったようです。

systemdは、この問題に対するまったく異なる(そしてより良い)ソリューションですscreen。スクリプトで実行するすべての操作にsystemdサービスオプションを使用できます。


一般的なMinecraftサーバーを実行するには、/etc/systemd/system/minecraft.service次のコンテンツでサーバーを作成します。

[Unit]
Description=Minecraft Server

[Service]
Type=simple
WorkingDirectory=/home/minecraft
ExecStart=java -Xmx1024M -Xms1024M -jar /home/minecraft/server.jar nogui
User=minecraft
Restart=on-failure

[Install]
WantedBy=multi-user.target

起動時に自動的に起動するように設定しますsystemctl enable minecraft

あなたはそれを制御する方法を尋ねています:

$ sudo systemctl start minecraft   # Starts the service if it wasn't running
$ sudo systemctl stop minecraft    # Stops the service
$ sudo systemctl restart minecraft # Restarts the service
$ sudo systemctl status minecraft  # Find out how the service is doing
$ sudo journalctl -u minecraft -f  # Monitor the logs

コンソールにコマンドを送信する方法を除くすべての操作を実行します。これを行うには、サーバーが受信するファイルを設定し、次のsystemdデバイスを作成してそのファイルにコマンドを作成できます。

/etc/systemd/system/minecraft.socket:

[Unit]
PartOf=minecraft.service

[Socket]
ListenFIFO=%t/minecraft.stdin

そして/etc/systemd/system/minecraft.service

[Unit]
Description=Minecraft Server

[Service]
Type=simple
WorkingDirectory=/home/minecraft
ExecStart=java -Xmx1024M -Xms1024M -jar /home/minecraft/server.jar nogui
User=minecraft
Restart=on-failure
Sockets=minecraft.socket
StandardInput=socket
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

これで、このファイルに内容を反映してコンソールコマンドを送信できます。

echo "help" > /run/minecraft.stdin
echo "/stop" > /run/minecraft.stdin

また、素晴らしい点は、カスタムコマンドシーケンスとcatファイル全体をコンソールに配置できることです。たとえば、プレイすると普遍的な健康保証、新しい世界を立ち上げ、人々にログインさせ、cat uhc.commands > /run/minecraft.stdinゲームルールを設定し、プレーヤーを分散させ、活動を始めることができます。

答え2

-dと-mと一緒にscreenを使用したくありません。なぜなら、このコマンドはバックグラウンドで実行され、スクリプトは私のサーバーを再起動し続けるからです。

だから使用-D代わりに-d(大文字注意!)

-D -m また、「分離」モードで画面を起動しますが、新しいプロセスを分岐しません。セッションが終了すると、コマンドは終了します。

screen新しいプロセスは作成されないため、実行java中はブロックされ、サーバーが停止すると終了します。

ボーナスとして、追加すると、-S spigotこの画面に接続してすべての端末の出力を監視できます(コマンドも送信できます!)。

そして…とにかく、systemdサービスを使用しています(そして実際にそうする必要があるので)、スクリプトでこの再起動ループを実行するのはなぜですか?Restart=always以下を使用して、systemdがこの問題を処理するようにします。RestartSec=5min

答え3

解決策が見つかりましたが使用できませんsystemctl status spigot

#!/bin/bash

while true; do
    cd /home/mcserver/Spigot
    echo Starting Spigot...
    screen -d -m -S Spigot java -jar spigot.jar
    SCREEN_NAME="Spigot"
    while screen -list | grep -q $SCREEN_NAME
    do
        sleep 1
    done
    echo Server has stopped, starting again in 5 minutes...
    sleep 300
done

スクリプトは、screenセッションが終了するのを待ちます。これで出力を表示したり、コンソールと対話したりできますscreen -r。または、複数の画面セッションを実行している場合は、追加を使用できますscreen -D -R "Spigot"

関連情報