web-dev-qa-db-ja.com

与えられた時間のbash後にプロセスを強制終了しますか?

別のプログラムを使用してDB接続を確立しようとするスクリプトがあり、プログラムのタイムアウト(2.5分)が長すぎます。この機能をスクリプトに追加したいと思います。

接続に5秒以上かかる場合は、プロセスを終了します
それ以外の場合は、スリープ/キルプロセスを終了します。

私が抱えている問題は、プロセスが強制終了されたときにbashがどのようにレポートするかです。これは、プロセスが同じシェルにバックグラウンドで存在するためです。これを行うためのより良い方法はありますか、またはkillコマンドのシェルをサイレントにするにはどうすればよいですか?

DB_CONNECTION_PROGRAM > $CONNECTFILE &
pid=$! 
(sleep 5; kill $pid) &
sleep_pid=$!
wait $pid

# If the DB failed to connect after 5 seconds and was killed
status=$? #Kill returns 128+n (fatal error)
if [ $status -gt 128 ]; then
    no_connection="ERROR: Timeout while trying to connect to $dbserver"
else # If it connected kill the sleep and any errors collect
    kill $sleep_pid
    no_connection=`sed -n '/^ERROR:/,$p' $CONNECTFILE`
fi
29
LF4

同じかどうかはわかりませんが、数年前に同様の問題を修正しました。しかし、私はプログラマーであり、Unixのようなシステム管理者ではないので、私のBash-fuはそれほど強力ではない可能性があるので、以下を塩味でお試しください...

基本的に私はフォーク、フォーク、フォークをしました:)

Out of memory 私の古いコード(私は驚くほど毎日毎日使用しています)を見つけた後、私のメモリが十分ではなかったため、Bashでは次のように機能しました。

commandThatMayHang.sh 2 > /dev/null 2>&1 &    (notice that last '&', we're forking)
MAYBE_HUNG_PID=$!
sleepAndMaybeKill.sh $MAYBE_HUNG_PID 2 > /dev/null 2>&1 &   (we're forking again)
SLEEP_AND_MAYBE_KILL_PID=$!   
wait $MAYBE_HUNG_PID > /dev/null 2>&1
if [ $? -eq 0 ]
    # commandThatMayHand.sh did not hang, fine, no need to monitor it anymore
    kill -9 $SLEEP_AND_MAYBE_KILL 2> /dev/null 2>&1
fi

ここで、sleepAndMaybeKill.shは、必要な時間だけスリープしてから、commandThatMayHand.shを強制終了します。

したがって、基本的に2つのシナリオは次のとおりです。

  1. コマンドは正常に終了し(5秒のタイムアウト前など)、waitコマンドが正常に終了するとすぐに停止します(「キラー」は不要になったため、強制終了します)

  2. コマンドがロックし、キラーがコマンドを強制終了する

いずれの場合も、コマンドが完了するとすぐに成功するか、タイムアウト後に失敗することが保証されます。

10
TacticalCoder

GNUタイムアウトと呼ばれるcoreutilsユーティリティがあります: http://www.gnu.org/s/coreutils/manual/html_node/timeout-invocation.html

あなたのプラットフォームでそれを持っているなら、あなたはそうすることができます:

timeout 5 CONNECT_TO_DB
if [ $? -eq 124 ]; then
    # Timeout occurred
else
    # No hang
fi
110
Itay Perl

2時間後にタイムアウトを設定し、この方法でjavaScriptThatStallsをループで100回再起動できます

seq 100|xargs -II timeout $((2 * 60 * 60)) javaScriptThatStalls
0
rubo77

私はこのbashスクリプト timeout.sh をAnthony Thyssen( his web )で見つけました。いいね。

0
waseq

プロセスがまだ実行されていない場合にエラーメッセージを出力したくないということですか?次に、stderrをリダイレクトするだけです:kill $pid 2>/dev/null

プロセスがまだ実行されているかどうかを確認することもできます。

if ps -p $pid >/dev/null; then kill $pid; fi
0
Kevin