我已经设置了一个 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
Run Code Online (Sandbox Code Playgroud)
我实际上可以查看spigot.jarusing的输出systemctl status spigot,但我也想控制服务器控制台,也许使用screen.
当我尝试这样做时:
screen -S "Spigot" java -jar spigot.jar
Run Code Online (Sandbox Code Playgroud)
我会得到Must be connected to a terminal错误。此命令仅适用于终端(而不适用于脚本),我可以使用screen -r.
有没有办法“绕过”这个屏幕错误?我已经尝试script /dev/null在屏幕命令之前放置。我不想将 screen 与 -d 和 -m 一起使用,因为它会在后台运行并且脚本会不断重新启动我的服务器。
我怀疑你偶然发现了这篇博文,它screen用来解决你的 minecraft 服务器在你停止时停止的问题$ java -jar spigot.jar,然后关闭你的 ssh 或 putty 会话。该方法似乎已成为关于如何运行 minecraft 服务器的标准答案,即使它不是必需的。
systemd 是解决这个问题的完全不同(更好)的解决方案,绕过了screen. 您可以使用 systemd 服务选项实现您在脚本中所做的一切。
要运行 vanilla 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
Run Code Online (Sandbox Code Playgroud)
将其设置为启动后自动启动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
Run Code Online (Sandbox Code Playgroud)
除了为您提供一种向控制台发送命令以执行此操作的方法之外,这可以完成所有操作,我们将设置一个文件,服务器将侦听该文件,您可以通过创建以下 systemd 单元来编写命令:
/etc/systemd/system/minecraft.socket:
[Unit]
PartOf=minecraft.service
[Socket]
ListenFIFO=%t/minecraft.stdin
Run Code Online (Sandbox Code Playgroud)
和/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
Run Code Online (Sandbox Code Playgroud)
现在您可以通过将内容回显到该文件中来发送控制台命令:
echo "help" > /run/minecraft.stdin
echo "/stop" > /run/minecraft.stdin
Run Code Online (Sandbox Code Playgroud)
同样很酷的是,您可以将自己的自定义命令序列和cat整个文件放入控制台。例如,如果你玩UHC,你可以开始一个新世界,让人们登录,然后cat uhc.commands > /run/minecraft.stdin设置游戏规则,传播玩家,并开始活动。
我不想将 screen 与 -d 和 -m 一起使用,因为它将在后台运行,并且脚本将不断重新启动我的服务器。
所以使用-D而不是-d(注意大写!)
-D -m 这也会以“分离”模式启动屏幕,但不会分叉新进程。如果会话终止,该命令将退出。
由于screen不会派生新进程,因此它将在java运行时阻塞,并在服务器停止时退出。
作为奖励,如果您添加,-S spigot您可以通过连接到该屏幕来监控任何终端的输出(甚至发送命令!)
而且...既然您无论如何都在使用 systemd 服务(而且您确实应该),为什么要在脚本中执行此重新启动循环?让 systemd 为您处理这个问题,使用Restart=always和RestartSec=5min