Skip to content

Instantly share code, notes, and snippets.

@samchouse
Created January 29, 2021 16:02
Show Gist options
  • Select an option

  • Save samchouse/7e5d016ba910d923fbec9e976a250971 to your computer and use it in GitHub Desktop.

Select an option

Save samchouse/7e5d016ba910d923fbec9e976a250971 to your computer and use it in GitHub Desktop.
Minecraft Server Management Script
#!/bin/bash
shopt -s nullglob
if [[ "$1" == '' ]]; then
:
elif [[ "$#" -gt "1" ]]; then
while getopts s: flag; do
case "${flag}" in
s)
server=${OPTARG}
shift
shift
;;
*)
exit 1
;;
esac
done
clear
else
read -r -p "What server would you like to use: " server
fi
service="$server-Server"
startCheckDelay=15
stopCheckDelay=15
stopDelay=10
restartCheckDelay=10
serverOptions='nogui'
username='ubuntu'
serverPath="/home/ubuntu/$server"
backupPath="$serverPath/backups"
unwanted=('logs' 'cache' 'backups' 'dump' 'version_history.json' 'usercache.json' 'eula.txt' 'usernamecache.json')
maxHeap=6144
minHeap=2048
me=$(whoami)
as_user() {
if [ "$me" == $username ]; then
bash -c "$1"
else
sudo su - $username -c "$1"
fi
}
mc_saveoff() {
if as_user "screen -ls | grep $service" >/dev/null; then
echo "$service is running, suspending saves..."
as_user "screen -p 0 -S $service -X eval 'stuff \"say World saving paused.\"\015'"
as_user "screen -p 0 -S $service -X eval 'stuff \"save-off\"\015'"
as_user "screen -p 0 -S $service -X eval 'stuff \"save-all\"\015'"
sleep 10
else
echo "$service is not running. Not suspending saves."
fi
}
mc_saveon() {
if as_user "screen -ls | grep $service" >/dev/null; then
echo "$service is running, re-enabling saves..."
as_user "screen -p 0 -S $service -X eval 'stuff \"save-on\"\015'"
as_user "screen -p 0 -S $service -X eval 'stuff \"say World saving resumed.\"\015'"
else
echo "$service is not running. Not resuming saves."
fi
}
mc_start() {
if as_user "screen -ls | grep $service" >/dev/null; then
echo "$service is already running!"
else
echo "Starting $service..."
cd "$serverPath" || exit 1
jars=(*.jar)
if [ "${#jars[@]}" -gt 1 ]; then
echo "Choose a server jar:"
selections=("${jars[@]}" 'Quit')
select serverJar in "${selections[@]}"; do
case $serverJar in
'')
echo "Invalid choice" >&2
;;
'Quit')
echo "Goodbye!"
exit
;;
*)
echo "You have selected: $serverJar"
break
;;
esac
done
elif [ "${#jars[@]}" -eq 1 ]; then
serverJar="${jars[0]}"
else
echo "No jar found in $PWD" >&2
exit 1
fi
command="java -Xmx${maxHeap}M -Xms${minHeap}M -jar $serverJar $serverOptions"
as_user "cd $serverPath && screen -dmS $service $command"
echo "Waiting $startCheckDelay seconds before checking if $service is running..."
sleep $startCheckDelay
if as_user "screen -ls | grep $service" >/dev/null; then
echo "$service is now running."
else
echo "Error! Could not start $service!"
fi
fi
}
mc_stop() {
if as_user "screen -ls | grep $service" >/dev/null; then
echo "Notifying users $service is stopping and then waiting $stopDelay seconds..."
as_user "screen -p 0 -S $service -X eval 'stuff \"say Server shutting down in $stopDelay seconds. Saving map...\"\015'"
as_user "screen -p 0 -S $service -X eval 'stuff \"save-all\"\015'"
sleep $stopDelay
echo "Stopping $service..."
as_user "screen -p 0 -S $service -X eval 'stuff \"stop\"\015'"
echo "Waiting $stopCheckDelay seconds before checking if $service is stopped..."
sleep $stopCheckDelay
else
echo "$service was not running."
fi
if as_user "screen -ls | grep $service" >/dev/null; then
echo "Error! $service could not be stopped."
else
echo "$service is stopped."
fi
}
mc_backup() {
now=$(date "+%Y-%m-%d_%Hh%Mm")
backupFile="$backupPath/${server}_${now}.tar"
mc_saveoff
cd "$serverPath" || exit
dir=(*)
for target in "${unwanted[@]}"; do
for i in "${!dir[@]}"; do
if [[ ${dir[i]} = "$target" ]]; then
unset 'dir[i]'
fi
done
done
for i in "${!dir[@]}"; do
updatedDir+=("${dir[i]}")
done
dir=("${updatedDir[@]}")
unset updatedDir
for i in "${dir[@]}"; do
echo "Backing up the server ($i)..."
as_user "tar -C $serverPath -rf $backupFile $i"
done
mc_saveon
echo "Compressing backup..."
as_user "gzip -f $backupFile"
echo "Done."
}
mc_command() {
command="$1"
if as_user "screen -ls | grep $service" >/dev/null; then
pre_log_len=$(wc -l "$server/logs/latest.log" | awk '{print $1}')
echo "$service is running... executing command"
as_user "screen -p 0 -S $service -X eval 'stuff \"$command\"\015'"
sleep 5
tail -n $(($(wc -l "$server/logs/latest.log" | awk '{print $1}') - pre_log_len)) "$server/logs/latest.log"
else
echo "$service is stopped."
fi
}
mc_attach() {
if as_user "screen -ls | grep $service" >/dev/null; then
as_user "screen -R $service"
else
echo "$service is stopped."
fi
}
mc_detach() {
if as_user "screen -ls | grep $service" >/dev/null; then
as_user "screen -d $service"
else
echo "$service is stopped."
fi
}
case "$1" in
start)
mc_start
;;
stop)
mc_stop
;;
restart)
if as_user "screen -ls | grep $service" >/dev/null; then
mc_stop
echo "Waiting $restartCheckDelay before restarting..."
sleep $restartCheckDelay
mc_start
else
echo "$service is stopped."
fi
;;
backup)
mc_backup
;;
attach)
mc_attach
;;
detach)
mc_detach
;;
status)
if as_user "screen -ls | grep $service" >/dev/null; then
echo "$service is running."
else
echo "$service is not running."
fi
;;
command)
if [ $# -gt 1 ]; then
shift
mc_command "$*"
else
echo "Must specify server command (try '?')"
fi
;;
*)
echo "Usage: $0 {start|stop|backup|status|restart|attach|detach|command \"command\"}"
exit 1
;;
esac
exit 0
@Bytekron
Copy link
Copy Markdown

Bytekron commented Apr 6, 2026

Cool script, gonna link it in a blog post on Minelist

It may need some overwork, but its a pretty good reference :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment