Hey, I noticed an error in your systemd script. Specifically in how you invoke the stuff command. This causes none of the commands sent to the screen session to execute. Rather, the following happens:
- You run
service minecraft@yourdirectory stop
- Your script sends the first command to the screen session via
stuff "say SERVER SHUTTING DOWN IN 5 SECONDS. SAVING ALL MAPS..."5
With this command, stuff sends the string "say SERVER SHUTTING DOWN IN 5 SECONDS. SAVING ALL MAPS..."
to the server console, alongside a specific keypress, represented by the '5'
. Normally, this should be enter, to execute the command in the server console. However, in screen the 5 stands for Numpad 5, as seen in the manpage of screen (Chapter 11.2 - Input Translation). That means that your command (and all subsequent commands) paste the command string into the console, followed by a five. So your script output on the console would look like this:
say SERVER SHUTTING DOWN IN 5 SECONDS. SAVING ALL MAPS...5save-all5stop5
- After all of that happens, the process just gets killed and the server does not properly shut down.
To fix this, you need to replace the Numpad 5 part in the stuff commands with the Enter key, which is represented by the string \015
.
To make it easy, here is my fixed script (modified slightly with a proper countdown, you can customize as you want of course):
[Unit]
Description=Minecraft Server: %i
After=network.target
[Service]
WorkingDirectory=/opt/minecraft/%i
User=minecraft
Group=minecraft
Restart=always
ExecStart=/usr/bin/screen -DmS mc-%i /usr/bin/java -Xmx2G -jar minecraft_server.jar nogui
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "say SERVER WILL SHUT DOWN IN 30 SECONDS. MAKE SURE YOU ARE IN A SAFE SPOT! SAVING ALL MAPS..."\015'
ExecStop=/bin/sleep 20
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "say SERVER SHUTTING DOWN IN 10 SECONDS. YOU BETTER HURRY UP NOW! SAVING ALL MAPS..."\015'
ExecStop=/bin/sleep 5
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "say 5..."\015'
ExecStop=/bin/sleep 1
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "say 4..."\015'
ExecStop=/bin/sleep 1
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "say 3..."\015'
ExecStop=/bin/sleep 1
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "say 2..."\015'
ExecStop=/bin/sleep 1
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "say 1..."\015'
ExecStop=/bin/sleep 1
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "save-all"\015'
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "stop"\015'
[Install]
WantedBy=multi-user.target
I tested it and the commands now get passed properly. You can check for yourself and also see the erroneous behaviour of your script by pulling the screen session to the foreground on a second terminal or ssh session with
su - minecraft
screen -r
and watching the console output. Dont forget to put the session back into the background afterwards with
Ctrl-a d
(Press Control and a at the same time, release both and then press d).
I hope that some people who setup their server with this guide see this, because not shutting the server down properly might lead to unexpected behaviour, glitches and data loss. Apart from this error, great and easy to follow guide!