我已经设置了一个 systemd 服务来运行我的 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
在屏幕命令之前。我不想将 screen 与 -d 和 -m 一起使用,因为它将在后台运行,并且脚本将不断重新启动我的服务器。
答案1
我怀疑你偶然发现了这篇博文它用于解决当您关闭 ssh 或 putty 会话screen
时您的 Minecraft 服务器停止的问题。$ 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
我不想将 screen 与 -d 和 -m 一起使用,因为它将在后台运行,并且脚本将不断重新启动我的服务器。
所以使用-D
而不是-d
(注意大写!)
-D -m 这也会以“分离”模式启动屏幕,但不会分叉新进程。如果会话终止,该命令将退出。
由于screen
不会派生新进程,因此它将在java
运行时阻塞,并在服务器停止时退出。
作为奖励,如果您添加,-S spigot
您可以通过连接到该屏幕来监控任何终端的输出(甚至发送命令!)
而且...既然您无论如何都在使用 systemd 服务(而且您确实应该),为什么要在脚本中执行此重新启动循环?让 systemd 为您处理这个问题,使用Restart=always
和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 -r
,或者如果我正在运行多个屏幕会话,我可以使用附加screen -D -R "Spigot"
。