ksh에서 "idql" 명령 시간이 초과되었습니다.

ksh에서 "idql" 명령 시간이 초과되었습니다.

아래는 내 코드의 일부입니다.

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 조건문에 지정된)을 계속 확인해야 하며, 추가로 "보류 중" 상태도 확인해야 한다는 것입니다. 명령이 idql5초 이상 걸리면 명령이 중단된 것으로 간주할 수 있습니다.

답변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/nullsh -i
  • /dev/null+를 누를 때 터미널에서 명령을 읽지 않도록 대화형 셸의 표준 입력을 리디렉션합니다 .CtrlC

관련 정보