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
, rspid
y rspname
desde 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 getopts
el 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 1
bandera le dice a la lectura que espere solo 1 carácter y no espere una nueva línea. la -r
bandera desactiva el tratamiento de caracteres especiales. En general, siempre debe usarlo -r
a 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?