Подтвердить что ты не робот

В чем разница между "else if" и "elif" в bash?

У меня есть следующая оболочка script, которая должна просто скомпоновать несколько файлов Java.ear/.war в JBoss:

SUCCESS=false
DEPLOY_PATH=/apps/jboss/server/default/deploy

E_NOARGS=75
M_USAGE="usage: $0 {rcm|hcm}"
M_MISSING_RCM="missing: rcm.war file not present"
M_MISSING_HCM="missing: hcm.ear or hcm.war file not present"

if [ -z "$1" ] 
then
  echo $M_USAGE
  exit $E_NOARGS
else
  M_START="deploying $1 ..."
  M_FINISH="finished deploying $1"
fi

until [ -z "$1" ]
do
  echo $M_START 
  case "$1" in
    rcm*)
      # do a hot-deploy of the rcm.war file
      # TODO: test if rcm.war file is present, error out if not
      if [ -e rcm.war ]
      then 
        cp -v rcm.war $DEPLOY_PATH/rcm.war
        SUCCESS=true
      else
        echo $M_MISSING_RCM
      fi
      ;;
    hcm*)
      # do a shutdown, deploy hcm.war, and restart jboss
      ps -ef | awk '/jboss/{print $2}' | xargs kill -s KILL

      HCM_DEPLOYED=false

      if [ -e hcm.ear ]
      then
        cp -v hcm.ear $DEPLOY_PATH/hcm.ear
        HCM_DEPLOYED=true
      else
        if [ -e hcm.war ]
        then
          cp -v hcm.war $DEPLOY_PATH/hcm.war
          HCM_DEPLOYED=true
        else 
          echo $M_MISSING_HCM
        fi
      fi

      if $HCM_DEPLOYED ;
      then
        # TODO: detect the hostname
        nohup /apps/jboss/bin/run.sh -b <HOSTNAME> & &> /dev/null
        SUCCESS=true
      fi
      ;;
    *)
      echo $M_USAGE
      exit 1
  esac
  shift
done

if $SUCCESS ;
then
  echo $M_FINISH
fi

В частности, раздел, который меня смущает, следующий:

      if [ -e hcm.ear ]
      then
        cp -v hcm.ear $DEPLOY_PATH/hcm.ear
        HCM_DEPLOYED=true
      else
        if [ -e hcm.war ]
        then
          cp -v hcm.war $DEPLOY_PATH/hcm.war
          HCM_DEPLOYED=true
        else 
          echo $M_MISSING_HCM
        fi
      fi

Я не могу заставить elif [ -e hcm.war ] корректно работать на удаленном сервере. Удаленный сервер работает bash 3.2.25 на redhat (если это имеет значение.) Я подозреваю, что мне просто не хватает какой-то придирчивой bash оболочки script detail.

Любые предложения?

4b9b3361

Ответ 1

Ваш код как опубликованный, кажется, работает.

Существует разница между elif .. fi AND else ; if ... fi. Истинный elif ... fi будет содержать меньше fi в конце, чем ваш код.

Ваш код, опубликованный, спрашивает: "Если hcm.ear существует, ТОГДА проверьте, есть ли hcm.war". Это то, что вы хотите? Другой логический путь к тесту будет "если hcm.ear не существует. ТОГДА проверьте, есть ли hcm.war."

Этот альтернативный логический путь выглядит как

  if [ -e hcm.ear ] ; then
    cp -v hcm.ear $DEPLOY_PATH/hcm.ear
    HCM_DEPLOYED=true
  elif [ -e hcm.war ] ; then
      cp -v hcm.war $DEPLOY_PATH/hcm.war
      HCM_DEPLOYED=true
  else 
    echo $M_MISSING_HCM
  fi

Надеюсь, это поможет.

Ответ 2

Это не прямой ответ на вопрос (elif vs else), но я бы сделал рефакторинг следующим образом:

HCM_DEPLOYED=true
cp -v hcm.ear "${DEPLOY_PATH}/" || cp -v hcm.war "${DEPLOY_PATH}/" || HCM_DEPLOYED=false
if [ ! ${HCM_DEPLOYED} ]; then
   echo "${M_MISSING_HCM}"
else
    # TODO: detect the hostname
    ...

т.е. всегда пытайтесь копировать, так как вы всегда хотите их выполнять, если кто-то не выполняет попытку следующего и т.д.

В стороне, вы всегда хотите обернуть пути и строки в кавычки. В противном случае путь, содержащий пробелы, приведет к разрыву приложения.