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)を起動します。このシェルは対話型なので、独自のシェルがあります。プロセスグループ
  • サブシェルは一緒にパイプされた2つのコマンドを実行します。これにより、同じプロセスグループ内で2つのコマンドを並列に実行できます。
  • 両方のコマンドで終わりkill 0、プロセスグループ内のすべてのコマンドを終了します。最初に終わるコマンド(idqlまたはsleep)は他のコマンドを終了します。
  • idqlパイプを通過しないように、ファイル記述子3の戻り状態を印刷します。ファイル記述子 3 はシェルのファイル記述子 1 にリダイレクトされ、コマンド置換がその fd の出力をキャプチャします。
  • /dev/null内部シェルから「終了した」メッセージを防ぐために、対話型シェルの標準エラーをリダイレクトします。エラー出力を表示するには、idqlリダイレクトする必要があります(idql 2>&4代わりにidql 2>/dev/null4>&2前に追加)。2>/dev/nullsh -i
  • /dev/null+を押したときに端末からコマンドを読み取らないように、対話型シェルの標準入力をリダイレクトします。CtrlC

関連情報