아래는 내 코드의 일부입니다.
idql -n $REPOSITORY_NAME.$cs -Udmadmin -P"" -R$DM_SCRIPTS/test.api > /dev/null 2>&1
if [ $? != 0 ]; then
echo " \c"
echo "ERROR: Cannot connect to: $REPOSITORY_NAME.$cs on $HOST"
else
echo " Successfully connected to: $REPOSITORY_NAME.$cs"
fi
이것이 서비스 모니터링에 사용하는 주요 논리입니다. 그러나 서비스가 중단되는 경우가 종종 발생하므로 위 코드 조각의 첫 번째 줄이 중단된 다음 계속되지 않습니다. 따라서 이러한 "서비스 중단" 상황을 포착할 수 없습니다.
가장 중요한 점은 기존 조건(if-else 조건문에 지정된)을 계속 확인해야 하며, 추가로 "보류 중" 상태도 확인해야 한다는 것입니다. 명령이 idql
5초 이상 걸리면 명령이 중단된 것으로 간주할 수 있습니다.
답변1
내 생각엔 네가 원하는 것 같아timeout
시스템의 일부 coreutils
이며 시스템에서 사용할 수 있어야 하는 명령
5초 후에 명령을 종료하려면 다음으로 변경하십시오.
timeout 5 iqdl -n $REPOSITORY_NAME.$cs ...
없는 경우 coreutils
여기에서 다운로드, 빌드 및 설치할 수 있습니다.http://www.gnu.org/software/coreutils/
또한보십시오:https://stackoverflow.com/questions/687948/timeout-a-command-in-bash-without-unnecessary-delay
답변2
솔루션을 수정할 수 있었습니다http://h30499.www3.hp.com/t5/System-Administration/Capturing-hung-command-in-a-script/td-p/5662103내 요구 사항을 충족시키기 위해.
나는 그것을 테스트했고 그것은 나에게 완벽하게 작동합니다. 귀하의 모든 도움에 감사드립니다.
#!/bin/ksh
WAITTIME=5
# run the idql command in the background, discarding any output
idql -n $REPOSITORY_NAME -Udmadmin -P"" -R"$DM_SCRIPTS/test.api" >/dev/null 2>&1 &
IDQL_PID=$!
# set up a timeout that will kill the idql command when
# $WAITTIME seconds has passed, unless it has completed before that.
(sleep $WAITTIME; kill $IDQL_PID 2>/dev/null) &
TIMEOUT_PID=$!
# wait for the idql command to either complete or get killed; read its return status
wait $IDQL_PID
RESULT=$?
# if the timeout is still running, stop it (ignore any errors)
kill $TIMEOUT_PID 2>/dev/null
# read the return status of the timeout process (we don't need it
# but running the wait function prevents it from remaining as a
# zombie process)
wait $TIMEOUT_PID
if [ $RESULT -eq 1 ];then
echo "something is wrong with $REPOSITORY_NAME, It seems to be down. Result - $RESULT"
elif [ $RESULT -eq 143 ];then
echo "Attention!!! ***$REPOSITORY_NAME seems to be HUNG*** Result - $RESULT"
else
echo "$REPOSITORY_NAME seems to be OK. Result - $RESULT"
fi
답변3
idql
일시 중단된 동안 루프에서 CPU 시간을 사용하는 경우 총 CPU 시간에 제한을 둘 수 있습니다.
( ulimit -t 5;
idql -n $REPOSITORY_NAME.$cs -Udmadmin -P"" -R$DM_SCRIPTS/test.api > /dev/null 2>&1 )
다른 이유로(예: 교착 상태) 차단되는 경우 idql
벽시계 시간에 따라 시간 초과되어야 합니다. 이는 다음으로 인한 해결 방법입니다.스티븐 히메네즈, 명령의 종료 상태를 얻기 위해 약간 수정되었습니다 idql
.
ret=$(sh -ic '{ { idql -n "$REPOSITORY_NAME.$cs" -Udmadmin -P"" -R"$DM_SCRIPTS/test.api" > /dev/null 2>&1;
echo $? >&3;
kill 0; } |
{ sleep 5; kill 0; } }' </dev/null 3>&1 2>/dev/null)
if [ -z "$ret" ]; then
echo "timed out"
elif [ "$ret" -ne 0 ]; then
echo "error $ret"
else
echo "ok"
fi
설명하다:
- 대화형 셸(
sh -i
)을 시작합니다. 이 쉘은 대화형이므로 자체 쉘이 있습니다.프로세스 그룹. - 서브셸은 함께 파이프된 두 개의 명령을 실행합니다. 이를 통해 동일한 프로세스 그룹 내에서 두 개의 명령을 병렬로 실행할 수 있습니다.
- 두 명령 모두 로 끝나며
kill 0
, 이는 프로세스 그룹 내의 모든 명령을 종료합니다. 먼저 끝나는 명령(idql
또는sleep
)은 다른 명령을 종료합니다. idql
파이프를 통과하지 않도록 파일 설명자 3의 반환 상태를 인쇄합니다. 파일 설명자 3은 셸의 파일 설명자 1로 리디렉션되어 명령 대체가 해당 fd의 출력을 캡처합니다./dev/null
내부 셸에서 "종료된" 메시지를 방지하기 위해 대화형 셸의 표준 오류를 리디렉션합니다 . 오류 출력을 보려면idql
리디렉션해야 합니다(idql 2>&4
대신idql 2>/dev/null
,4>&2
앞에 추가).2>/dev/null
sh -i
/dev/null
+를 누를 때 터미널에서 명령을 읽지 않도록 대화형 셸의 표준 입력을 리디렉션합니다 .CtrlC