![스크립트 실행 실패](https://linux55.com/image/88884/%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%20%EC%8B%A4%ED%96%89%20%EC%8B%A4%ED%8C%A8.png)
실행 중인 Java 프로세스의 힙 및 스레드 덤프를 캡처하는 스크립트를 만들었습니다.
#! /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
그러나 오류가 발생하지 않고 사례 설명에 대한 내 스크립트가 실패합니다. ${hoption}
평가되지 않았다고 생각합니다 .
답변1
스크립트가 실행되는 동안 stdin에서 읽어서는 안 되며 , hoption
대부분 의 다른 프로그램과 마찬가지로 명령줄에서 옵션으로 제공해야 합니다. 어렵게 들리지만 bash 내장 기능을 사용하면 실제로 매우 쉽습니다 ( 요약은 참고자료 참조).rspid
rspname
getopts
help getopts
이렇게 하면 쉘의 명령줄 기록만 사용하여 동일한 매개변수로 스크립트를 쉽게 테스트할 수 있으며(즉, 동일한 값을 계속해서 입력할 필요가 없음), 더 중요한 것은 다른 스크립트에서도 쉽게 테스트할 수 있다는 것입니다. 이 스크립트를 사용하려면 올바른 매개변수를 사용하여 호출하세요.
다음은 이를 수행하는 버전입니다(몇 가지 사소한 개선 사항 포함). 그리고 고정 변수 참조 - 내가 매번 어떻게 하는지 참고하세요.사용된변수를 큰따옴표로 묶었나요? 당신도 똑같이해야합니다. )
#! /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
답변2
읽은 후 디버그 라인을 추가하여 echo ${hoption}
올바르게 설정되었는지 확인하세요.
또한 각 사례에 에코를 추가하여 해당 사례에 도달했음을 나타냅니다.
이 경우 단일 문자만 찾고 있으므로 다음과 같은 방법으로 읽기를 사용합니다.
read -r -n 1 hoption
이 -n 1
플래그는 읽기에 새 줄이 아닌 문자 1개만 기다리라고 지시합니다. 이 -r
플래그는 특수 문자 처리를 비활성화합니다. 일반적으로 -r
그렇게 하지 말아야 할 명확한 이유가 없는 한 항상 사용해야 합니다. 그렇지 않으면 이상한 동작이 발생할 수 있습니다.
스크립트를 테스트했는데 적어도 내 환경에서는 hoption의 값을 얻은 것 같습니다(변경된 사항 없음). 위의 방법으로 문제가 해결되지 않으면 나타나는 오류 메시지는 무엇입니까?