Skip to content

Instantly share code, notes, and snippets.

@metrovoc
Last active November 10, 2025 06:52
Show Gist options
  • Select an option

  • Save metrovoc/66e24c803d03f0d4872f86f35dd7cadc to your computer and use it in GitHub Desktop.

Select an option

Save metrovoc/66e24c803d03f0d4872f86f35dd7cadc to your computer and use it in GitHub Desktop.
A simple rollback script for minecraft servers
#!/bin/bash
# --- Configuration ---
# The name of the screen session your Minecraft server is running in.
SCREEN_SESSION_NAME="archwood"
# The script used to start the server. This will be terminated to prevent auto-restart.
SERVER_WRAPPER_SCRIPT="startserver.sh"
# A UNIQUE string from your server's startup command to reliably identify the process.
# This has been VERIFIED by the 'ps aux' command on your system.
SERVER_PROCESS_IDENTIFIER="unix_args.txt"
# The directory where your world data is stored.
WORLD_DIR="world"
# The directory where your backups are stored.
BACKUP_DIR="simplebackups/world"
# Timeout in seconds to wait for the server to gracefully stop.
SHUTDOWN_TIMEOUT=120
# --- Script Functions ---
# Function to send a command to the screen session, correctly formatted.
send_to_screen() {
screen -S "$SCREEN_SESSION_NAME" -X stuff "$1"
}
# Function to check if the specific Minecraft Java process is running.
is_server_java_running() {
# This check is based on the proven output of 'ps aux' on your system.
# It is the most reliable method for this environment.
ps aux | grep java | grep "$SERVER_PROCESS_IDENTIFIER" | grep -v grep > /dev/null
}
# --- Script Start ---
# STEP 1: Select the backup file first.
echo "---------------------------------------------------------------"
echo "Starting the Final Proven Rollback Process..."
echo "---------------------------------------------------------------"
echo "[INFO] Searching for available backups in '$BACKUP_DIR'..."
cd "$BACKUP_DIR" || { echo "[ERROR] Backup directory '$BACKUP_DIR' not found."; exit 1; }
backups=(*.zip)
if [ ${#backups[@]} -eq 0 ] || [ ! -f "${backups[0]}" ]; then
echo "[ERROR] No backups found in the '$BACKUP_DIR' directory."
cd ../..
exit 1
fi
echo "Please select a backup to restore from the list below:"
PS3="Enter the number of the backup (or Ctrl+C to cancel): "
select backup_file in "${backups[@]}"; do
if [[ -n "$backup_file" ]]; then
echo "[INFO] You have selected: $backup_file"
break
else
echo "Invalid selection. Please try again."
fi
done
cd ../..
# STEP 2: Final confirmation before any action is taken.
echo ""
echo "---------------------------------------------------------------"
echo "!!! FINAL CONFIRMATION !!!"
echo "The script will now run automatically and perform the following:"
echo " 1. Gracefully stop the Minecraft server (if running)."
echo " 2. Terminate the auto-restart script."
echo " 3. Create a final backup of the current world."
echo " 4. DELETE the current world."
echo " 5. Restore the backup: '$backup_file'."
echo " 6. Restart the Minecraft server."
echo "---------------------------------------------------------------"
read -p "Are you sure you want to proceed? (y/n) " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Rollback cancelled by user."
exit 0
fi
# STEP 3: Execute the automated rollback process.
echo ""
echo "Confirmation received. Starting automated process..."
echo ""
# Stop the server if it's running, using the robust check.
if is_server_java_running; then
echo "[ACTION] Server process found. Sending graceful 'stop' command..."
send_to_screen $'stop\r'
echo -n "[INFO] Waiting for server to shut down (timeout: ${SHUTDOWN_TIMEOUT}s)..."
SECONDS=0
while is_server_java_running; do
if [ $SECONDS -ge $SHUTDOWN_TIMEOUT ]; then
echo "\n[ERROR] Server did not stop within $SHUTDOWN_TIMEOUT seconds."
echo "Please check the server console ('screen -r $SCREEN_SESSION_NAME') and stop it manually."
exit 1
fi
echo -n "."
sleep 2
done
echo "\n[SUCCESS] Minecraft Java process has terminated safely."
# Now, kill the wrapper script to prevent restart.
echo "[ACTION] Terminating the auto-restart wrapper script..."
if pkill -f "$SERVER_WRAPPER_SCRIPT" > /dev/null; then
echo "[SUCCESS] Auto-restart script terminated."
else
echo "[INFO] Auto-restart script was not found running, which is expected."
fi
sleep 1 # Brief pause to ensure OS has processed the pkill
else
echo "[INFO] Server Java process is not running. Skipping shutdown."
fi
# Create a backup of the current world
TEMP_BACKUP_NAME="world_before_rollback_$(date +'%Y-%m-%d_%H-%M-%S').zip"
echo "[ACTION] Backing up the current world to '$BACKUP_DIR/$TEMP_BACKUP_NAME'..."
if [ -d "$WORLD_DIR" ]; then
if zip -rq "$BACKUP_DIR/$TEMP_BACKUP_NAME" "$WORLD_DIR"; then
echo "[SUCCESS] Backup of the current world created."
else
echo "[ERROR] Failed to create a backup. Aborting."
exit 1
fi
else
echo "[INFO] Current world directory not found. Skipping backup."
fi
# Delete the current world
echo "[ACTION] Deleting the current world..."
if rm -rf "$WORLD_DIR"; then
echo "[SUCCESS] Current world deleted."
else
echo "[ERROR] Failed to delete the current world. Aborting."
exit 1
fi
# Restore the selected backup
echo "[ACTION] Restoring the selected backup: $backup_file..."
if unzip -q "$BACKUP_DIR/$backup_file" -d .; then
echo "[SUCCESS] Backup restored."
else
echo "[ERROR] Failed to restore backup. Manual intervention required."
exit 1
fi
# Restart the server
echo "[ACTION] Restarting the Minecraft server in screen session '$SCREEN_SESSION_NAME'..."
send_to_screen $"./$SERVER_WRAPPER_SCRIPT\r"
# Final message
echo ""
echo "---------------------------------------------------------------"
echo "ROLLBACK COMPLETE!"
echo "Server restart command has been sent."
echo "You can re-attach to the screen session to monitor startup using:"
echo "screen -r $SCREEN_SESSION_NAME"
echo "---------------------------------------------------------------"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment