Falha na execução do script

Falha na execução do script

Eu criei um script para capturar o despejo de heap e thread de um processo Java em execução.

#! /bin/bash

myhost=$(uname)

if [ "${myhost}" == "SunOS" ]; then

HEAPLOGS="/export/home/${USER}/applog/heapdump"
THREADLOGS="/export/home/${USER}/applog/threaddump"

elif [ "${myhost}" == "Linux" ]; then

HEAPLOGS="/opt/app/${USER}/applog/heapdump"
THREADLOGS="/opt/app/${USER}/applog/threaddump"

fi

DAY=$(date +%Y.%m.%d)
NOW=$(date +%Y.%m.%d-%H.%M.%S)
EXPIRE=30

echo " Please select your option "
echo
echo " Heap-Dump : 0 "
echo " Thread-Dump : 1 "
echo " Both of above : 2 "

read hoption


echo
echo " Enter PID :"
read rspid
echo " Enter InstanceName :"
read rspname

case ${hoption} in 

         0)
            # generate java heapdump
              jmap -dump:format=b,file=${HEAPLOGS}/${rspname}-${NOW}.hprof ${rspid}"
              chmod 644 ${HEAPLOGS}/${rspname}-${NOW}.hprof
      ;;
         1)
            # generate java threaddump
              jstack ${rspid} > ${THREADLOGS}/${rspname}-${NOW}.log"
              chmod 644 ${THREADLOGS}/${rspname}-${NOW}.log
      ;;
         2)
            # generate java heapdump
              jmap -dump:format=b,file=${HEAPLOGS}/${rspname}-${NOW}.hprof ${rspid}"
              chmod 644 ${HEAPLOGS}/${rspname}-${NOW}.hprof
            # generate java threaddump
              jstack ${rspid} > ${THREADLOGS}/${rspname}-${NOW}.log"
              chmod 644 ${THREADLOGS}/${rspname}-${NOW}.log
      ;;

esac

Mas meu script falha na declaração de caso sem gerar nenhum erro. Acredito ${hoption}que não esteja sendo avaliado.

Responder1

Em vez de ler hoptione rspidde rspnamestdin enquanto o script está em execução, você deve considerá-los como opções na linha de comando, assim como a maioria dos outros programas faz. Isso parece difícil, mas na verdade é bastante fácil usando o bash-builtin getopts(veja help getoptsum resumo)

Dessa forma, você pode testar facilmente seu script com os mesmos argumentos apenas usando o histórico de linha de comando do seu shell (ou seja, NÃO precisa digitar os mesmos valores repetidamente) e, mais importante, você pode usar facilmente esse script em outros scripts, apenas chamando-o com os argumentos certos.

Aqui está uma versão que faz isso (além de algumas pequenas melhorias. E correções para a cotação de variáveis ​​- observe como toda vez que euusadouma variável, coloquei-a entre aspas duplas? Você deveria também.)

#! /bin/bash

case "$(uname)" in
   Linux) APPPATH='/opt/app/' ;;
   SunOS) APPPATH='/export/home/' ;;
       *) echo "Unknown OS" >/dev/stderr ; exit 1 ;;
esac

HEAPLOGS="$APPPATH/${USER}/applog/heapdump"
THREADLOGS="$APPPATH/${USER}/applog/threaddump"

DAY=$(date +%Y.%m.%d)
NOW=$(date +%Y.%m.%d-%H.%M.%S)
EXPIRE=30

usage() {
  [ -z "$*" ] || printf "%s\n\n" "$@"

  cat <<__EOF__
Usage: $0 <-h|-t|-b> -e <expire> -p <pid> -i <instance>

  -h    Heap-Dump
  -t    Thread-Dump
  -b    Both of above

  -e    Expiry time (defaults to 30)

  -p    PID
  -i    Instance Name

__EOF__

exit 1
}

unset hoption rspid rspname

# process command line options
while getopts 'htbe:p:i:' opt ; do
  case "$opt" in
    h|t|b) [ -z "$hoption" ] && hoption="$opt" || \
           usage "Only use one of -h, -t, or -b"
           ;;

    e) EXPIRE="$OPTARG" ;;

    p) rspid="$OPTARG" ;;
    i) rspname="$OPTARG" ;;

    *) usage ;;
  esac
done

[ -z "$hoption" ] && usage "Must provide one of -h, -t, or -b"
[ -z "$rspid" ] && usage "'-p <PID>' is required"
[ -z "$rspname" ] && usage "'-i <instance>' is required"

case "$hoption" in
  h)  # generate java heapdump
      jmap -dump:format=b,file="${HEAPLOGS}/${rspname}-${NOW}.hprof" "${rspid}"
      chmod 644 "${HEAPLOGS}/${rspname}-${NOW}.hprof"
        ;;

  t) # generate java threaddump
     jstack "${rspid}" > "${THREADLOGS}/${rspname}-${NOW}.log"
     chmod 644 "${THREADLOGS}/${rspname}-${NOW}.log"
     ;;


  b) # generate java heapdump
     jmap -dump:format=b,file="${HEAPLOGS}/${rspname}-${NOW}.hprof" "${rspid}"
     chmod 644 "${HEAPLOGS}/${rspname}-${NOW}.hprof"

     # generate java threaddump
     jstack "${rspid}" > "${THREADLOGS}/${rspname}-${NOW}.log"
     chmod 644 "${THREADLOGS}/${rspname}-${NOW}.log"
     ;;
esac

Responder2

Adicione uma linha de depuração echo ${hoption}depois de lê-la para confirmar que está sendo definida corretamente.
Coloque também um eco em cada caso indicando que você chegou a esse caso.

Nesse caso, como você está procurando apenas um único caractere, eu usaria read desta forma:

read -r -n 1 hoption

O -n 1sinalizador diz ao read para esperar apenas 1 caractere e não esperar por uma nova linha. o -rsinalizador desativa o tratamento especial de caracteres. Em geral, você deve sempre usar, -ra menos que tenha uma razão explícita para não fazê-lo - caso contrário, um comportamento estranho pode resultar.

Testei o script e parece estar obtendo o valor de hoption, pelo menos no meu ambiente (sem nenhuma alteração). Se o procedimento acima não resolver o seu problema, qual é a mensagem de erro que você está recebendo?

informação relacionada