以下は私のコードの一部です。
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
)を起動します。このシェルは対話型なので、独自のシェルがあります。プロセスグループ。 - サブシェルは一緒にパイプされた2つのコマンドを実行します。これにより、同じプロセスグループ内で2つのコマンドを並列に実行できます。
- 両方のコマンドで終わり
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