Jump to content

Talking to a running MC server using shell scripts ??

- - - - -

  • Please log in to reply
6 replies to this topic

#1
bbqroast

bbqroast

    Codecall Addict

  • Members
  • PipPipPipPipPipPipPip
  • 554 posts
  • Location:/etc/passwd
Hiya!
On my server I have a running MC server (java- it runs in console), the script currently looks like this.

cd '/home/jed/minecraft-server/'

date=$(date +"%m-%d-%Y")

time=$(date +"%H:%M:%S")

echo $time ' ' $date

cp -r 'world/' 'backups/serverStartBak.'$date'.'$time

java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui

This code creates a backup of the world with a time-stamp before starting the MC server Java app. However once the program is running I want to run the command "save-off" (this stops it from automatically saving to the world file) and then every 15 minutes run the command "save-all" before repeating the backup process in the above code (line 5)- This will basically mean that I can restore the server if anyone griefs (I have a program to help me patch together chunks so as not to rollback the entire server).

Really the only thing I need help with is the inserting commands part the rest should be easy.

p.s. When I loaded this code in notepad it was all one line so I fixed that then copy pasted it into codecall, However when I did this all the lines were pushed apart as if I had entered twice and one which I had forgot to put on its own line was now on its own line. Obviously CODECALL could see the new lines that notepad couldn't... anyone know how to fix this??
Please, write clearly with proper structure. Double spacing makes the text feel un-jointed, Capitalizing Every Word Means People Stop Before Every Word Sub-Consciously Which Is A Pain In The Backside, and use code tags! (The right most styling box).

#2
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200
I assume from your description that the .jar file will need exclusive access to the command line to read input. You could start this process in a detached screen (see GNU screen) and serve commands through this command to negotiate with the server.

Although I am unable to test at the moment, the steps should be:

  • Run the server starting command through screen, in detatched mode (-m requires a new session, even if already in one)
screen -d -m screen_session_name java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui 

bbqroast said:

I want to run the command "save-off"

  • You can send what you will require with the following command to the active screen session. -S accepts a session name, and -X runs a command, stuff is a screen command.
screen  -d -m -S screen_session_name -X stuff 'save-off' `echo -ne '\015'`
This echo will be required to simulate a newline, you can as well simply do
'saveoff
'

bbqroast said:

then every 15 minutes run the command "save-all"

  • Set up a cron script for every fifteen minutes (5,20,35,50 * * * *) with I assume the command to save all server data as above, then cp -r (recursive) the folder to a backup location.
You may need to apply the setuid bit to the screen command to allow it to be shared between users.
Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.

#3
bbqroast

bbqroast

    Codecall Addict

  • Members
  • PipPipPipPipPipPipPip
  • 554 posts
  • Location:/etc/passwd
That's a bit confusing...
Could you post the completed script (not for me to use but just to see how it all works) the main thing that is confusing me is the "stuff"
Please, write clearly with proper structure. Double spacing makes the text feel un-jointed, Capitalizing Every Word Means People Stop Before Every Word Sub-Consciously Which Is A Pain In The Backside, and use code tags! (The right most styling box).

#4
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200
Ah , this post slipped by me I apologize. I found one online that should work:
#!/bin/bash

# /etc/init.d/minecraft

# version 0.3.2 2011-01-27 (YYYY-MM-DD)


### BEGIN INIT INFO

# Provides:   minecraft

# Required-Start: $local_fs $remote_fs

# Required-Stop:  $local_fs $remote_fs

# Should-Start:   $network

# Should-Stop:    $network

# Default-Start:  2 3 4 5

# Default-Stop:   0 1 6

# Short-Description:    Minecraft server

# Description:    Starts the minecraft server

### END INIT INFO


#Settings

SERVICE='minecraft_server.jar'

USERNAME="minecraft"

MCPATH='/home/minecraft/minecraft'

CPU_COUNT=1

INVOCATION="java -Xmx1024M -Xms1024M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalPacing -XX:ParallelGCThreads=$CPU_COUNT -XX:+AggressiveOpts -jar minecraft_server.jar nogui"

BACKUPPATH='/media/remote.share/minecraft.backup'


ME=`whoami`

as_user() {

  if [ $ME == $USERNAME ] ; then

    bash -c "$1"

  else

    su - $USERNAME -c "$1"

  fi

}


mc_start() {

  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null

  then

    echo "Tried to start but $SERVICE was already running!"

  else

    echo "$SERVICE was not running... starting."

    cd $MCPATH

    as_user "cd $MCPATH && screen -dmS minecraft $INVOCATION"

    sleep 7

    if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null

    then

      echo "$SERVICE is now running."

    else

      echo "Could not start $SERVICE."

    fi

  fi

}


mc_saveoff() {

        if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null

	then

		echo "$SERVICE is running... suspending saves"

		as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonly...\"\015'"

                as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-off\"\015'"

                as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"

                sync

		sleep 10

	else

                echo "$SERVICE was not running. Not suspending saves."

	fi

}


mc_saveon() {

        if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null

	then

		echo "$SERVICE is running... re-enabling saves"

                as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-on\"\015'"

                as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write...\"\015'"

	else

                echo "$SERVICE was not running. Not resuming saves."

	fi

}


mc_stop() {

        if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null

        then

                echo "$SERVICE is running... stopping."

                as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'"

                as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"

                sleep 10

                as_user "screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'"

                sleep 7

        else

                echo "$SERVICE was not running."

        fi

        if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null

        then

                echo "$SERVICE could not be shut down... still running."

        else

                echo "$SERVICE is shut down."

        fi

}



mc_update() {

  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null

  then

    echo "$SERVICE is running! Will not start update."

  else

    MC_SERVER_URL=http://www.minecraft.net/download/minecraft_server.jar?v=`date | sed "s/[^a-zA-Z0-9]/_/g"`

    as_user "cd $MCPATH && wget -q -O $MCPATH/minecraft_server.jar.update $MC_SERVER_URL"

    if [ -f $MCPATH/minecraft_server.jar.update ]

    then

      if `diff $MCPATH/minecraft_server.jar $MCPATH/minecraft_server.jar.update >/dev/null`

        then 

          echo "You are already running the latest version of $SERVICE."

        else

          as_user "mv $MCPATH/minecraft_server.jar.update $MCPATH/minecraft_server.jar"

          echo "Minecraft successfully updated."

      fi

    else

      echo "Minecraft update could not be downloaded."

    fi

  fi

}


mc_backup() {

   echo "Backing up minecraft world"

   if [ -d $BACKUPPATH/world_`date "+%Y.%m.%d"` ]

   then

     for i in 1 2 3 4 5 6

     do

       if [ -d $BACKUPPATH/world_`date "+%Y.%m.%d"`-$i ]

       then

         continue

       else

         as_user "cd $MCPATH && cp -r world $BACKUPPATH/world_`date "+%Y.%m.%d"`-$i"

         break

       fi

     done

   else

     as_user "cd $MCPATH && cp -r world $BACKUPPATH/world_`date "+%Y.%m.%d"`"

     echo "Backed up world"

   fi

   echo "Backing up the minecraft server executable"

   if [ -f "$BACKUPPATH/minecraft_server_`date "+%Y.%m.%d"`.jar" ]

   then

     for i in 1 2 3 4 5 6

     do

       if [ -f "$BACKUPPATH/minecraft_server_`date "+%Y.%m.%d"`-$i.jar" ]

       then

         continue

       else

         as_user "cd $MCPATH && cp minecraft_server.jar \"$BACKUPPATH/minecraft_server_`date "+%Y.%m.%d"`-$i.jar\""

         break

       fi

     done

   else

     as_user "cd $MCPATH && cp minecraft_server.jar \"$BACKUPPATH/minecraft_server_`date "+%Y.%m.%d"`.jar\""

   fi

   echo "Backup complete"

}



#Start-Stop here

case "$1" in

  start)

    mc_start

    ;;

  stop)

    mc_stop

    ;;

  restart)

    mc_stop

    mc_start

    ;;

  update)

    mc_stop

    mc_backup

    mc_update

    mc_start

    ;;

  backup)

    mc_saveoff

    mc_backup

    mc_saveon

    ;;

  status)

    if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null

    then

      echo "$SERVICE is running."

    else

      echo "$SERVICE is not running."

    fi

    ;;


  *)

  echo "Usage: /etc/init.d/minecraft {start|stop|update|backup|status|restart}"

  exit 1

  ;;

esac


exit 0

The coding is a little awkward to look at (I am sure you could write a better one if you tried) although it appears to be working.


bbqroast said:

the main thing that is confusing me is the "stuff"
It is purely a command used by screen to combine strings in to an argument to be sent to the process (with eval)
Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.

#5
bbqroast

bbqroast

    Codecall Addict

  • Members
  • PipPipPipPipPipPipPip
  • 554 posts
  • Location:/etc/passwd
Hmmm...
Maybe I'll just stick with your first post, this "screen" stuff sounds interesting...
Please, write clearly with proper structure. Double spacing makes the text feel un-jointed, Capitalizing Every Word Means People Stop Before Every Word Sub-Consciously Which Is A Pain In The Backside, and use code tags! (The right most styling box).

#6
bbqroast

bbqroast

    Codecall Addict

  • Members
  • PipPipPipPipPipPipPip
  • 554 posts
  • Location:/etc/passwd
Can you point me to a relative tutorial?
I found tons but they all assumed I was doing this myself not through a script (most of them appear to be for SHH connections so you don't lose all your work when you lose conection).
Please, write clearly with proper structure. Double spacing makes the text feel un-jointed, Capitalizing Every Word Means People Stop Before Every Word Sub-Consciously Which Is A Pain In The Backside, and use code tags! (The right most styling box).

#7
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200
I do believe most of everything is in here: Screen User's Manual

There are a lot of things you can do with screen, the main thing you require though are sessions, as your server program will run in a single session and you must pass commands to it based on your selected action (save, stop, etc.)

Try to write a simple script to send very simple hello world like commands to your server, and if it works then try to wrap them in functions next and see if it works.
Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users