Screen (command-line program) bug?
- by VioletCrime
fired up my Minecraft server again after about a year off. My server used to run 11.04, which has since been upgraded to 12.04; I lost my management scripts in the upgrade (thought I'd backed up the user's home directory), but whatever, I enjoy developing stuff like that anyways. However, this time around, I'm running into issues.
I start the Minecraft server using a detached screen, however the script is unable to 'stuff' commands into the screen instance until I attach to the screen then detach again? Once I do that, I can stuff anything I want into the server's terminal using the -X option, until I stop/start the server again, then I have to reattach and detach in order to restore functionality?
Here's the manager script:
#!/bin/bash
#Name of the screen housing the server (set with the -S flag at startup)
SCREENNAME=minecraft1
#Name of the folder housing the Minecraft world
FOLDERNAME=world1
startServer (){
if screen -list | grep "$SCREENNAME" > /dev/null
then
echo "Cannot start Minecraft server; it is already running!"
else
screen -dmS $SCREENNAME java -Xmx1024M -Xms1024M -jar minecraft_server.jar
sleep 2
if screen -list | grep "$SCREENNAME" > /dev/null
then
echo "Minecraft server started; happy mining!"
else
echo "ERROR: Minecraft server failed to start!"
fi
fi;
}
stopServer (){
if screen -list | grep "$SCREENNAME" > /dev/null
then
echo "Server is running. Giving a 1-minute warning."
screen -S $SCREENNAME -X stuff "/say Shutting down (halt) in one minute."
screen -S $SCREENNAME -X stuff $'\015'
sleep 45
screen -S $SCREENNAME -X stuff "/say Shutting down (halt) in 15 seconds."
screen -S $SCREENNAME -X stuff $'\015'
sleep 15
screen -S $SCREENNAME -X stuff "/stop"
screen -S $SCREENNAME -X stuff $'\015'
else
echo "Server is not running; nothing to stop."
fi;
}
stopServerNow (){
if screen -list | grep "$SCREENNAME" > /dev/null
then
echo "Server is running. Giving a 5-second warning."
screen -S $SCREENNAME -X stuff "/say EMERGENCY SHUTDOWN! 5 seconds to halt."
screen -S $SCREENNAME -X stuff $'\015'
sleep 5
screen -S $SCREENNAME -X stuff "/stop"
screen -S $SCREENNAME -X stuff $'\015'
else
echo "Server is not running; nothing to stop."
fi;
}
restartServer (){
if screen -list | grep "$SCREENNAME" > /dev/null
then
echo "Server is running. Giving a 1-minute warning."
screen -S $SCREENNAME -X stuff "/say Shutting down (restart) in one minute."
screen -S $SCREENNAME -X stuff $'\015'
sleep 45
screen -S $SCREENNAME -X stuff "/say Shutting down (restart) in 15 seconds."
screen -S $SCREENNAME -X stuff $'\015'
sleep 15
screen -S $SCREENNAME -X stuff "/stop"
screen -S $SCREENNAME -X stuff $'\015'
sleep 2
startServer
else
echo "Cannot restart server: it isn't running."
fi;
}
#In order for this function to work, a directory 'backup/$FOLDERNAME' must exist in the same
#directory that '$FOLDERNAME' resides
backupWorld (){
if screen -list | grep "$SCREENNAME" > /dev/null
then
echo "Server is running. Giving a 1-minute warning."
screen -S $SCREENNAME -X stuff "/say Shutting down (backup) in one minute."
screen -S $SCREENNAME -X stuff $'\015'
screen -S $SCREENNAME -X stuff "/say Server should be down for no more than a few seconds."
screen -S $SCREENNAME -X stuff $'\015'
sleep 45
screen -S $SCREENNAME -X stuff "/say Shutting down for backup in 15 seconds."
screen -S $SCREENNAME -X stuff $'\015'
sleep 15
screen -S $SCREENNAME -X stuff "/stop"
screen -S $SCREENNAME -X stuff $'\015'
fi
sleep 2
if screen -list | grep $SCREENNAME > /dev/null
then
echo "Server is still running? Error."
else
cd ..
tar -czvf backup0.tar.gz $FOLDERNAME
mv backup0.tar.gz backup/$FOLDERNAME
cd backup/$FOLDERNAME
rm backup10.tar.gz
mv backup9.tar.gz backup10.tar.gz
mv backup8.tar.gz backup9.tar.gz
mv backup7.tar.gz backup8.tar.gz
mv backup6.tar.gz backup7.tar.gz
mv backup5.tar.gz backup6.tar.gz
mv backup4.tar.gz backup5.tar.gz
mv backup3.tar.gz backup4.tar.gz
mv backup2.tar.gz backup3.tar.gz
mv backup1.tar.gz backup2.tar.gz
mv backup0.tar.gz backup1.tar.gz
cd ../../$FOLDERNAME
screen -dmS $SCREENNAME java -Xmx1024M -Xms1024M -jar minecraft_server.jar;
sleep 2
if screen -list | grep "$SCREENNAME" > /dev/null
then
echo "Minecraft server restarted; happy mining!"
else
echo "ERROR: Minecraft server failed to start!"
fi
fi;
}
printCommands (){
echo
echo "$0 usage:"
echo
echo "Start : Starts the server on a detached screen."
echo "Stop : Stop the server; includes a 1-minute warning."
echo "StopNOW : Stops the server with only a 5-second warning."
echo "Restart : Stops the server and starts the server again."
echo "Backup : Stops the server (1 min), backs up the world, and restarts."
echo "Help : Display this message."
}
#Forces case-insensitive string comparisons
shopt -s nocasematch
#Primary 'Switch'
if [[ $1 = "start" ]]
then
startServer
elif [[ $1 = "stop" ]]
then
stopServer
elif [[ $1 = "stopnow" ]]
then
stopServerNow
elif [[ $1 = "backup" ]]
then
backupWorld
elif [[ $1 = "restart" ]]
then
restartServer
else
printCommands
fi