La ejecución del script falló

La ejecución del script falló

He creado una secuencia de comandos para capturar el montón y el volcado de subprocesos de un proceso Java en ejecución.

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

Pero mi secuencia de comandos falla en la declaración del caso sin arrojar ningún error. Creo ${hoption}que no está siendo evaluado.

Respuesta1

En lugar de leer hoption, rspidy rspnamedesde stdin mientras se ejecuta el script, debes tomarlos como opciones en la línea de comando, tal como lo hacen la mayoría de los otros programas. Esto suena difícil, pero en realidad es bastante fácil usando el bash incorporado getopts(consulte help getoptsel resumen)

De esa manera, puede probar fácilmente su secuencia de comandos con los mismos argumentos simplemente usando el historial de la línea de comandos de su shell (es decir, NO tiene que escribir los mismos valores una y otra vez) y, lo que es más importante, puede usar fácilmente esta secuencia de comandos en otras secuencias de comandos. simplemente llamándolo con los argumentos correctos.

Aquí hay una versión que hace eso (más algunas mejoras menores. Y corrige las comillas variables; observe cómo cada vez queusadouna variable, ¿la he encerrado entre comillas dobles? Tu también deberías.)

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

Respuesta2

Agregue una línea de depuración echo ${hoption}después de leerla para confirmar que está configurada correctamente.
También pon un eco en cada caso indicando que has llegado a ese caso.

En este caso, como solo buscas un carácter, usaría read de esta manera:

read -r -n 1 hoption

La -n 1bandera le dice a la lectura que espere solo 1 carácter y no espere una nueva línea. la -rbandera desactiva el tratamiento de caracteres especiales. En general, siempre debe usarlo -ra menos que tenga una razón explícita para no hacerlo; de lo contrario, se puede producir un comportamiento extraño.

Probé el script y parece estar obteniendo el valor de hoption, al menos en mi entorno (sin ningún cambio). Si lo anterior no soluciona su problema, ¿cuál es el mensaje de error que recibe?

información relacionada