Handle SIGTERM to stop Minecraft gracefully
- Set up SIGTERM signal trap to invoke stop_server - Ensure proper process exit and cleanup after the server stops - Create makefile to build, clean, and install builds
This commit is contained in:
@@ -1,5 +1,44 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if the minecraft screen is still running
|
||||
check_screen() {
|
||||
if [ "$(screen -ls | grep -cE '[0-9]+\.minecraft')" -eq 1 ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to stop the server gracefully
|
||||
stop_server() {
|
||||
if check_screen; then
|
||||
# Run 'stop' inside screen and wait for the screen to exit
|
||||
/usr/bin/screen -p 0 -S minecraft -X eval 'stuff "stop"\015'
|
||||
wait "$STRACE_PID"
|
||||
|
||||
# Stop tail -f to stdout
|
||||
if kill -0 "$TAIL_PID" 2>/dev/null; then
|
||||
kill "$TAIL_PID"
|
||||
fi
|
||||
|
||||
# Check only this script is running (PID 1) and pgrep (2 PIDs total)
|
||||
PGREP_OUTPUT="$(pgrep .)"
|
||||
if ! [ "$(echo "$PGREP_OUTPUT" | wc -l)" -eq 2 ]; then
|
||||
echo "[WARN] Some processes might not have exited:"
|
||||
echo "$PGREP_OUTPUT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Exit cleanly
|
||||
echo "[INFO] Server stopped gracefully"
|
||||
exit 0
|
||||
else
|
||||
echo "[ERROR]: Can't find which screen to use"
|
||||
screen -ls
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Enable debug mode
|
||||
DEBUG="${DEBUG:-false}"
|
||||
if [ "$DEBUG" = "true" ]; then
|
||||
@@ -32,8 +71,9 @@ while IFS='=' read -r ENVVAR VALUE ; do
|
||||
rm "${FILE}.bak"
|
||||
fi
|
||||
else
|
||||
[ "$DEBUG" = "true" ] && \
|
||||
if [ "$DEBUG" = "true" ]; then
|
||||
echo "[DEBUG] \"$ENVVAR\" doesn't have the prefix \"$PREFIX\""
|
||||
fi
|
||||
fi
|
||||
done < <(env)
|
||||
|
||||
@@ -43,17 +83,33 @@ if [ "$DEBUG" = "true" ]; then
|
||||
cat "$FILE"
|
||||
fi
|
||||
|
||||
# Pre-create the screen log
|
||||
touch screenlog.0
|
||||
# Set up a SIGTERM signal trap to stop the server
|
||||
trap 'stop_server' SIGTERM
|
||||
|
||||
# Run server in screen (without attaching)
|
||||
echo "[INFO] Starting Minecraft server"
|
||||
/usr/bin/screen -dmS minecraft -L \
|
||||
bash -c "
|
||||
sleep 0.5
|
||||
[ $DEBUG = true ] && echo '[DEBUG] Starting server'
|
||||
/usr/bin/java $JVM_OPTS -jar server.jar --nogui
|
||||
"
|
||||
bash -c "/usr/bin/java $JVM_OPTS -jar server.jar --nogui"
|
||||
|
||||
# Tail screen log to container stdout
|
||||
[ "$DEBUG" = "true" ] && echo "[DEBUG] Tailing screenlog.0"
|
||||
tail -f screenlog.0
|
||||
# Get screen PID
|
||||
[ "$DEBUG" = "true" ] && screen -ls
|
||||
SCREEN_PID="$(
|
||||
screen -ls | grep -oE '[0-9]+\.minecraft' | cut -d. -f1
|
||||
)"
|
||||
|
||||
# Check screen PID
|
||||
if ! kill -0 "$SCREEN_PID" 2>/dev/null; then
|
||||
echo "[ERROR] Cannot find Minecraft screen (PID: \"$SCREEN_PID\")"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Output logs to stdout (touch in case slow to create)
|
||||
touch screenlog.0
|
||||
tail -f screenlog.0 &
|
||||
TAIL_PID="$!"
|
||||
|
||||
# Wait for screen to exit
|
||||
strace -e exit -e signal=none -p "$SCREEN_PID" 2>/dev/null &
|
||||
STRACE_PID="$!"
|
||||
[ "$DEBUG" = "true" ] && ps aux
|
||||
wait "$STRACE_PID"
|
||||
|
Reference in New Issue
Block a user