Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I have been fiddling with this code for a few days. Mind you I am a beginner. I just want to get my script to be able to download a remote file, and scan MineCraft plugins. I got the scan plugins to work, but I'm having two other issues. One, I can't get the mc_addplugin to work correctly, and I get a Unexpected EOF and unexpected end of document when running any other command besides mc_scanplugins or mc_start

bash: -c: line 0: unexpected EOF while looking for matching `"'
bash: -c: line 1: syntax error: unexpected end of file

Help would be so much appreciated! Thanks in advance.

#!/bin/bash
# /etc/init.d/craftbukkit
# version 0.9.1 2012-07-06 (YYYY-MM-DD)

### BEGIN INIT INFO
# Provides:               craftbukkit
# 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:      Starts craftbukkit server
# Description:            Starts and controls the craftbukkit server
### END INIT INFO

# SETTINGS
SERVICE='craftbukkit-1.2.5-R1.0.jar'
OPTIONS='nogui'
USERNAME='smith'

# LIST ALL THE WORLDS IN YOUR CRAFTBUKKIT SERVER FOLDER
WORLDS[1]='world'
WORLDS[2]='world_nether'
WORLDS[3]='world_the_end'
WORLDS[4]='flat_world'

MCPATH='/var/www/servers/Foundation'
PLUGINSPATH='/var/www/servers/Foundation/plugins'
TEMPPLUGINS='/var/www/servers/Foundationplugins/temp_plugins'
BACKUPPATH='/var/www/servers/Foundation/backup'

CPU_COUNT=2
INVOCATION="java -Xmx2024M -Xms2024M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalPacing -XX:ParallelGCThreads=$CPU_COUNT -XX:+AggressiveOpts -jar $SERVICE $OPTIONS"

ME=`whoami`
as_user() {
  if [ $ME == $USERNAME ] ; then
    bash -c "$1"
  else
    su - $USERNAME -c "$1"
  fi
}

mc_start() {
  if  pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "$SERVICE is already running!"
  else
    echo "Starting $SERVICE..."
    cd $MCPATH
    as_user "cd $MCPATH && screen -dmS craftbukkit $INVOCATION"
    sleep 7
    if pgrep -u $USERNAME -f $SERVICE > /dev/null
    then
      echo "$SERVICE is now running."
    else
      echo "Error! Could not start $SERVICE!"
    fi
  fi
}

mc_saveoff() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "$SERVICE is running... suspending saves"
    as_user "screen -p 0 -S craftbukkit -X eval 'stuff \"say The server is preforming a backup. Server going to read-only mode. Do not build...\"\015'"
    as_user "screen -p 0 -S craftbukkit -X eval 'stuff \"save-off\"\015'"
    as_user "screen -p 0 -S craftbukkit -X eval 'stuff \"save-all\"\015'"
    sync
    sleep 10
  else
    echo "$SERVICE is not running. Not suspending saves."
  fi
}

mc_save() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "$SERVICE is running... Saving worlds..."
    as_user "screen -p 0 -S craftbukkit -X eval 'stuff \"save-all\"\015'"
    sync
    sleep 10
    echo "Save complete!"
  else
    echo "$SERVICE is not running. Cannot save!"
  fi
}

mc_saveon() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "$SERVICE is running... re-enabling saves"
    as_user "screen -p 0 -S craftbukkit -X eval 'stuff \"save-on\"\015'"
    as_user "screen -p 0 -S craftbukkit -X eval 'stuff \"say Server backup has completed. Server going to read-write mode. You can now continue building...\"\015'"
  else
    echo "$SERVICE is not running. Not resuming saves."
  fi
}

mc_stop() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "Stopping $SERVICE"
    as_user "screen -p 0 -S craftbukkit -X eval 'stuff \"say $SERVERNAME is shutting down in 30 seconds! Please stop what you are doing. Check back later, we'll be back!\"\015'"
    as_user "screen -p 0 -S craftbukkit -X eval 'stuff \"save-all\"\015'"
    sleep 30
    as_user "screen -p 0 -S craftbukkit -X eval 'stuff \"stop\"\015'"
    sleep 7
  else
    echo "$SERVICE was not running."
  fi
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "Error! $SERVICE could not be stopped."
  else
    echo "$SERVICE is stopped."
  fi
}

mc_update() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "$SERVICE is running! Will not start update."
  else
    MC_SERVER_URL=http://dl.bukkit.org/latest-rb/craftbukkit.jar
    as_user "cd $MCPATH && wget -q -O $MCPATH/craftbukkit_server.jar.update $MC_SERVER_URL"
    if [ -f $MCPATH/craftbukkit_server.jar.update ]
    then
      if `diff $MCPATH/$SERVICE $MCPATH/craftbukkit_server.jar.update >/dev/null`
      then 
        echo "You are already running the latest version of $SERVICE. Update anyway? [Y/n]"
            select yn in "Yes" "No"; do
                case $yn in
                    Yes )   as_user "mv $MCPATH/$SERVICE $MCPATH/${SERVICE}_old.jar"
                            as_user "mv $MCPATH/craftbukkit_server.jar.update $MCPATH/$SERVICE"
                            echo "$SERVICE updated successfully!"; break;;
                    No )    echo "The update was not installed! Removing temporary files and exiting..."
                            as_user "rm $MCPATH/craftbukkit_server.jar.update" exit;;
                    esac
            done
      else
        as_user "mv $MCPATH/$SERVICE $MCPATH/${SERVICE}_old.jar"
        as_user "mv $MCPATH/craftbukkit_server.jar.update $MCPATH/$SERVICE"
        echo "$SERVICE updated successfully!"
      fi
    else
      echo "$SERVICE update could not be downloaded."
    fi
  fi
}

    mc_addplugin() {
        if pgrep -u $USERNAME -f $SERVICE > /dev/null
        then
            echo "$SERVICE is running! Please stop the service before adding a plugin."
        else
            echo "Paste the URL to the .JAR Plugin..."
            read JARURL
            JARNAME=$(basename "$JARURL")
            if [ -d "$TEMPPLUGINS" ]
            then
                as_user "cd $PLUGINSPATH && wget -r -A.jar $JARURL -o temp_plugins/$JARNAME"
            else
                as_user "cd $PLUGINSPATH && mkdir $TEMPPLUGINS && wget -r -A.jar $JARURL -o temp_plugins/$JARNAME"
            fi
            if [ -f "$TMPDIR/$JARNAME" ]
            then
                if [ -f "$PLUGINSPATH/$JARNAME" ]
                then
                    if `diff $PLUGINSPATH/$JARNAME $TMPDIR/$JARNAME >/dev/null`
                    then 
                        echo "You are already running the latest version of $JARNAME."
                    else
                        NOW=`date "+%Y-%m-%d_%Hh%M"`
                        echo "Are you sure you want to overwrite this plugin? [Y/n]"
                        echo "Note: Your old plugin will be moved to the "$TEMPPLUGINS" folder with todays date."
                        select yn in "Yes" "No"; do
                            case $yn in
                                Yes ) as_user "mv $PLUGINSPATH/$JARNAME $TEMPPLUGINS/${JARNAME}_${NOW} && mv $TEMPPLUGINS/$JARNAME $PLUGINSPATH/$JARNAME"; break;;
                                No ) echo "The plugin has not been installed! Removing temporary plugin and exiting..."
                                    as_user "rm $TEMPPLUGINS/$JARNAME"; exit;;
                            esac
                        done
                        echo "Would you like to start the $SERVICE now? [Y/n]"
                        select yn in "Yes" "No"; do
                            case $yn in
                                Yes ) mc_start; break;;
                                No ) "$SERVICE not running! To start the service run: /etc/init.d/craftbukkit start"; exit;;
                                esac
                        done
                    fi
                else
                    echo "Are you sure you want to add this new plugin? [Y/n]"
                    select yn in "Yes" "No"; do
                        case $yn in
                            Yes ) as_user "mv $PLUGINSPATH/$JARNAME $TEMPPLUGINS/${JARNAME}_${NOW} && mv $TEMPPLUGINS/$JARNAME $PLUGINSPATH/$JARNAME"; break;;
                            No ) echo "The plugin has not been installed! Removing temporary plugin and exiting..."
                                as_user "rm $TEMPPLUGINS/$JARNAME"; exit;;
                        esac
                    done
                    echo "Would you like to start the $SERVICE now? [Y/n]?"
                    select yn in "Yes" "No"; do
                        case $yn in
                            Yes ) mc_start; break;;
                            No ) "$SERVICE not running! To start the service run: /etc/init.d/craftbukkit start"; exit;;
                        esac
                    done
                fi
            else
                echo "Failed to download the plugin from the URL you specified!"
                exit;
            fi
        fi
    }

mc_scanplugins() {
    if [ "$(ls -A $PLUGINSPATH)" ]
    then

        shopt -s nullglob
        PLUGINS=($PLUGINSPATH/*.jar)
        i=1
        for f in "${PLUGINS[@]}"
        do
            echo "${i}: $f"
            PLUGIN[$i]=$f
            i=$(( $i + 1 ))
        done

        echo "Enter the ID of a plugin you want removed, or any other key to cancel."

        read INPUT

        if [ ! -z "${INPUT##*[!0-9]*}" ]
        then
            if [ -f "${PLUGIN[INPUT]}" ]
            then
                echo "Removing plugin..."
                JAR=$(basename ${PLUGIN[INPUT]})
                JARNAME=${JAR%.jar}
                as_user "rm -f ${PLUGIN[INPUT]}"
                sleep 2
                as_user "cd $PLUGINSPATH && rm -rf ./${JARNAME}"
                if [ -f "${PLUGINSPATH}/${JARNAME}" ]
                then
                    echo "Plugin folder could not be removed..."
                fi
                echo "Plugin removed."
            else
                echo "${PLUGIN[INPUT]}"
                echo "Invalid plugin! Does not exist! Canceling..."
                exit;
            fi
        else
            echo "Canceling..."
            exit;
        fi
    else
        echo "You have no plugins installed."
        exit;
    fi
}

mc_backup() {
   mc_saveoff

   for i in "${WORLDS[@]}"; do 
   NOW=`date "+%Y-%m-%d_%Hh%M"`
   BACKUP_FILE="$BACKUPPATH/${i}_${NOW}.tar"
   echo "Backing up world: $i..."
   #as_user "cd $MCPATH && cp -r $i $BACKUPPATH/${i}_`date "+%Y.%m.%d_%H.%M""`
   as_user "tar -C \"$MCPATH\" -cf \"$BACKUP_FILE\" $i"
   done

   echo "Backing up $SERVICE"
   as_user "tar -C \"$MCPATH\" -rf \"$BACKUP_FILE\" $SERVICE"
   #as_user "cp \"$MCPATH/$SERVICE\" \"$BACKUPPATH/craftbukkit_server_${NOW}.jar\""

   mc_saveon

   echo "Compressing backup..."
   as_user "tar -cvzf $BACKUPPATH/server_backup_${NOW}.tar.gz $MCPATH"
   echo "Backup has completed successfully."
}

mc_command() {
  command="$1";
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    pre_log_len=`wc -l "$MCPATH/server.log" | awk '{print $1}'`
    echo "$SERVICE is running... executing command"
    as_user "screen -p 0 -S craftbukkit -X eval 'stuff \"$command\"\015'"
    sleep .1 # assumes that the command will run and print to the log file in less than .1 seconds
    # print output
    tail -n $[`wc -l "$MCPATH/server.log" | awk '{print $1}'`-$pre_log_len] "$MCPATH/server.log"
  fi
}

#Start-Stop here
case "$1" in
  start)
    mc_start
    ;;
  stop)
    mc_stop
    ;;
  restart)
    mc_stop
    mc_start
    ;;
  save)
    mc_save
    ;;
  update)
    mc_stop
    mc_backup
    mc_update
    mc_start
    ;;
  scanplugins)
    mc_scanplugins
    ;;
  addplugin)
    mc_addplugin
    ;;
  backup)
    mc_backup
    ;;
  status)
    if pgrep -u $USERNAME -f $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 'help'?)"
    fi
    ;;

  *)
  echo "Usage: $0 {start|stop|update|backup|status|restart|command \"server command\"}"
  exit 1
  ;;
esac

exit 0
share|improve this question
    
I'm not an expert but I think if you want to use a \ in your code you have to escape it as well like this \\ otherwise it will try to escape whatever character is coming after it. –  Corey Whitaker Jul 10 '12 at 3:57
add comment

2 Answers

up vote 1 down vote accepted

Teach a man how to fish:

Read the error message carefully and try to figure where it comes from

In this case we have:

bash: -c: line 0: unexpected EOF while looking for matching `"'
bash: -c: line 1: syntax error: unexpected end of file

Q: Look at the script. Where do we have a call to 'bash' with a -c (command) option?

A: inside the as_user() function, we have a call:

bash -c "$1"

Now, $1 here is the first argument passed to the as_user() function, so we look again at the script and find where as_user() is being called, and with which argument.

Some of these arguments are complex with 3 levels of escaping/quoting so they are suspect.

You may add a simple debugging statement inside 'as_user' as the first line before anything else gets executed:

echo '$1 is:' $1

Which would print the command just before the failure, and make it obvious what the bad argument is.

More generally: you can conveniently debug shell scripts by adding tracing (aka 'echo'). Simply change the 1st line of the script to:

 #!/bin/bash -x

and every command would be printed just before it is executed, making the connection between the call and the error obvious. There's also -v (verbose) which will print every line as it is parsed, before all history/command/param/file expansions, but I find -v much less useful when debugging than -x. In rare cases I just use both: -vx to track the expansions that happen before execution in detail.

HTH

share|improve this answer
    
Thank you so much! I will get down and look into this. Seems debugging is the same as PHP besides the bash header -x. Convenient that is. I hope this sets me off on my way in bash programming. Thank you again! –  WASasquatch Jul 10 '12 at 17:50
add comment

After counting the characters in your script (a SMOP), I noticed that you had an ODD number (49) of "'" characters. Around line 105, you have an unescaped "'":

as_user "screen -p 0 -S craftbukkit -X eval 'stuff \"say $SERVERNAME is shutting down in 30 seconds! Please stop what you are doing. Check back later, we'll be back!\"\015'"

Try being more formal: "..., we will be back..."

Seriously, one unescaped "'" will confuse the parsing of the remainder of the script (where is the new "matching "'"?).

Fix this, then use -x and -v, and read man bash.

share|improve this answer
    
I knew it had to be something that because the backup worked fine, but I failed to realize I changed all the strings between the two versions. Thanks so much. Got the original working just gotta figure out my download problem now. Where it says the file doesn't exist in the $TEMPPLUGINS dir, when it totally does. Lol –  WASasquatch Jul 11 '12 at 19:05
    
you're blessed with a very good eye, waltinator. Oh well, I know you counted them, but you're blessed either way :) –  arielf Jul 18 '12 at 8:02
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.