GNUタイムアウトに相当するPOSIXですか?


14

GNU coreutils timeoutコマンドは、特定のスクリプトの状況に非常に便利で、実行が速い場合はコマンドの出力を使用でき、時間がかかりすぎる場合はスキップできます。

timeoutPOSIXで指定されたユーティリティのみを使用する基本的な動作を概算するにはどうすればよいですか?


(私はそれがの組み合わせを含むことができると思っていますwaitsleepkillそして他に何が、おそらく私はより簡単なアプローチを欠けているを知っています。)


3
シェルスクリプトでのタイムアウトを参照してください。ただし、POSIX以前のシステムへの移植性を要求し、バックグラウンドプロセスを含む一部のソリューションで除外されるstdinとstdoutを保持する必要があるため、これは重複とは見なしません。
ジル 'SO-悪であるのをやめる'

command & pid=$! ; sleep 5 && kill $pid
パンディア

1
@Pandyaはわずかな競合状態を引き起こしません。command急速に終了pidすると、killコマンドが実行される前に別のプロセスが再利用される可能性がわずかにありますか?実動コードではそれは望ましくありません
ワイルドカード

解決しようとしている根本的な問題について詳しく説明していただけますか?timeoutプログラムをコンパイルして使用するだけではどうですか?
ジェームズヤングマン

2
@JamesYoungman、あなたは移植性のためのスクリプト書くことにあまり精通しいないと思います。POSIX準拠(またはPOSIX指定)の方法を要求することは、移植性を意図していることを意味します。ソースコードをバイナリにコンパイルすることは非常に移植性が低く、企業のセキュリティポリシーによっては、運用サーバーにコンパイラがまったくインストールさていない場合があります。
ワイルドカード

回答:


2

私のアプローチはこれです:

  • バックグラウンドプロセスとしてコマンドを実行1

  • バックグラウンドプロセス2として「ウォッチドッグタイマー」を実行する

  • 親シェルで終了シグナルをトラップするハンドラーをセットアップします

  • 両方のプロセスが完了するまで待ちます。最初に終了するプロセスは、終了信号を親に送信します。

  • 親のトラップハンドラーは、ジョブ制御を介して両方のバックグラウンドプロセスを強制終了します(定義のいずれかによって既に終了していますが、PIDを使用していないため、その強制終了は無害です。以下を参照)

システムPIDではなく、強制終了するバックグラウンドプロセスを特定するために、シェルのジョブコントロールID(このシェルインスタンス内では明確なID)を使用して、コメントで解決される可能性のある競合状態を回避しようとしました。

#!/bin/sh

TIMEOUT=$1
COMMAND='sleep 5'

function cleanup {
    echo "SIGTERM trap"
    kill %1 %2
}

trap cleanup SIGTERM

($COMMAND; echo "Command completed"; kill $$) &
(sleep $TIMEOUT; echo "Timeout expired"; kill $$) &

wait
echo "End of execution"

TIMEOUT=10(ウォッチドッグの前にコマンドが終了する)の結果:

$ ./timeout.sh 10
Command completed
SIGTERM trap
End of execution

TIMEOUT=1(ウォッチドッグはコマンドの前に終了します)の結果:

$ ./timeout.sh 1
Timeout expired
SIGTERM trap
End of execution

以下のための結果TIMEOUT=5(「ほとんど」同時に終了ウォッチドッグコマンド):

./tst.sh 5
Timeout expired
Command completed
SIGTERM trap
End of execution

これはPOSIX準拠ではありません。(a)関数定義が必要でcleanup() { ...; }あり、(b)ジョブ制御がPOSIXで指定されていないbash機能であるためです(ただし、kshや他にもあります)。しかし、素晴らしいスクリプトです!
ワイルドカード

あなたはまた、とのより良い行うことができますtimeout="$1"; shift(exec "$@"; echo "Command completed"; kill $$)いうより引数リストを再wordsplitting。
ワイルドカード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.