如何使用屏幕控制systemd服务?

ada*_*009 5 bash gnu-screen

我已经设置了一个 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 一起使用,因为它会在后台运行并且脚本会不断重新启动我的服务器。

Ste*_*art 8

我怀疑你偶然发现了这篇博文,它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设置游戏规则,传播玩家,并开始活动。

  • 多么棒的答案啊!最后,一个优雅(且标准)的解决服务器“stdin”问题的解决方案! (3认同)

Mes*_*ion 3

我不想将 screen 与 -d 和 -m 一起使用,因为它将在后台运行,并且脚本将不断重新启动我的服务器。

所以使用-D而不是-d(注意大写!)

-D -m 这也会以“分离”模式启动屏幕,但不会分叉新进程。如果会话终止,该命令将退出。

由于screen不会派生新进程,因此它将在java运行时阻塞,并在服务器停止时退出。

作为奖励,如果您添加,-S spigot您可以通过连接到该屏幕来监控任何终端的输出(甚至发送命令!)

而且...既然您无论如何都在使用 systemd 服务(而且您确实应该),为什么要在脚本中执行此重新启动循环?让 systemd 为您处理这个问题,使用Restart=alwaysRestartSec=5min