emptyset emptyset - 3 years ago 207
Bash Question

What is the difference between "else if" and "elif" in bash?

I've got the following shell script that's supposed to simply stage a few Java .ear/.war files to 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


The section in particular that confuses me is this one:

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


I can't seem to get
elif [ -e hcm.war ]
to work correctly on the remote server. The remote server is running bash 3.2.25 on redhat (if that makes any difference.) I suspect I'm just missing some picky bash shell script detail.

Any suggestions?

Answer Source

Your code as posted seems to work.

There is a difference between elif .. fi AND else ; if ... fi. A true elif ... fi will have one fewer fi at the end than your code.

Your code as posted, asks, "if hcm.ear exists THEN check if there is an hcm.war". Is that what you want? The other logic path to test would be "if hcm.ear doesn't exist THEN check if there an hcm.war."

That alternate logic path looks like

  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

I hope this helps.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download