意外的 EOF 和文档结束

意外的 EOF 和文档结束

我已经摆弄这个代码几天了。请注意,我是个初学者。我只想让我的脚本能够下载远程文件并扫描 MineCraft 插件。我让扫描插件工作了,但我遇到了另外两个问题。第一,我无法让 mc_addplugin 正常工作,并且在运行除 mc_scanplugins 或 mc_start 之外的任何其他命令时,我都会收到意外的 EOF 和意外的文档结束

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

非常感谢您的帮助!提前致谢。

#!/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

答案1

授人以鱼不如授人以渔:

仔细阅读错误信息并尝试找出错误来源

在这种情况下,我们有:

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

问:看一下脚本。我们在哪里使用 -c(命令)选项调用“bash”?

答:在 as_user() 函数内部,我们有一个调用:

bash -c "$1"

现在,这里的 $1 是传递给 as_user() 函数的第一个参数,因此我们再次查看脚本并找到调用 as_user() 的位置以及使用哪个参数。

其中一些参数非常复杂,有 3 个级别的转义/引用,因此值得怀疑。

您可以在执行任何其他操作之前在“as_user”内添加一个简单的调试语句作为第一行:

echo '$1 is:' $1

它将在失败之前打印命令,并清楚地表明错误的参数是什么。

更一般地:您可以通过添加跟踪(又名“echo”)来方便地调试 shell 脚本。只需将脚本的第一行更改为:

 #!/bin/bash -x

并且每个命令都会在执行之前打印出来,使得调用和错误之间的联系显而易见。还有-v(详细)将打印每一行按照解析方式,在所有历史/命令/参数/文件扩展之前,但我发现-v在调试时用处不大-X。在极少数情况下,我会同时使用两者:-vx详细跟踪执行之前发生的扩展。

高血压

答案2

在计算了脚本 (SMOP) 中的字符数后,我注意到“ '”字符的数量为奇数 (49)。在第 105 行左右,有一个未转义的“ '”:

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'"

尝试更加正式一点:“......我们会回来的......”

认真地说,一个未转义的“ '”会混淆脚本其余部分的解析(新的“匹配的” 在哪里'?)。

修复此问题,然后使用-x-v,并阅读man bash

相关内容