A execução do script falhou

3

Eu criei um script para capturar o heap e o dump de 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 instrução case sem gerar nenhum erro. Eu acredito que ${hoption} não está sendo avaliado.

    
por Naresh 23.05.2016 / 15:27

2 respostas

3

Em vez de ler hoption , rspid e rspname de stdin enquanto o script está sendo executado, você deve tomá-los como opções na linha de comando, assim como a maioria dos outros programas. Isso parece difícil, mas é realmente muito fácil usando o bash-builtin getopts (veja help getopts para um resumo)

Dessa forma, você pode facilmente testar 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 facilmente usar esse script outros scripts, apenas chamando-os com os argumentos corretos.

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

#! /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
    
por 24.05.2016 / 03:40
2

Adicione uma linha de depuração de echo ${hoption} depois que ela for lida para confirmar que está sendo definida corretamente.
Coloque também um eco em cada caso, indicando que você chegou nesse caso.

Neste caso, uma vez que você está apenas procurando por um único caractere, eu usaria a leitura desta maneira:

read -r -n 1 hoption

A -n 1 sinaliza para que a leitura espere apenas 1 caractere e não espere por uma nova linha. o sinalizador -r desativa o tratamento de caractere especial. Em geral, você deve sempre usar -r , a menos que tenha uma razão explícita para não - um comportamento estranho pode resultar de outra forma.

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

    
por 23.05.2016 / 15:50