タイムアウトを設定したいbashスクリプトがあります。たとえば、スクリプトの実行に50秒以上かかると、0で終了します。スクリプト内で実行する必要があり、コマンドがスクリプトを呼び出す方法を変更することはできません。
最良のアプローチは何ですか?
タイムトラップのようなものがありますか?
すべてのコードをループに入れることもできますが、この場合はできません。
答え1
包装紙が必要です。
最も明確な方法は、元のスクリプトの名前を変更し、タイムアウト時に元のスクリプトを呼び出すラッパースクリプトをその場所に作成することです。これに対するバリエーションは、スクリプト自体とは異なる名前でリンクを作成することです。スクリプトの呼び出し方法によって、スクリプトで何が起こるかが決まります。しばらくすると明らかになります。
引数なしでスクリプトを呼び出す場合は、この内部ラッパーをスクリプトに追加できます。パラメータtimeout
のスイッチを使用して自分自身を呼び出します$1
。
#!/usr/bin/env bash
TIMEOUT=10
WRAPPER=FALSE
if [ "$1" != FALSE ]; then
timeout "$TIMEOUT" "$0" "$WRAPPER"
exit
fi
#the proper script
echo Here\'s the original script starting.
sleep 11
echo End of the original script.
したがって、以前のソリューションに戻って$0
スクリプトがどのように呼び出されるかを確認するために使用できます。ファイルですか、リンクですか?
新しい実行可能ファイル/リンクが望ましくないか生成できず、元の呼び出しでパラメータを使用している場合は、別のスイッチを使用できます。たとえば、一時ファイルを使用できます。これには、問題が発生した場合に備えてファイルをクリーンアップする必要があるいくつかの特殊なケースが含まれます。 PPID をスイッチとして使用することもできます。親コマンドがサブコマンドと同じ場合、スクリプトは正しく実行され、それ以外の場合はタイムアウト後に独自に実行されます。
答え2
他の場所で答えを受けたようですが、ここでできることがあります。
このコマンドが実行された時間(秒単位)を返すコマンド(追加)。Sin times は秒だけを返します。)
ps -p "<process-id>" -o times=
また必要があるかもしれません
pgrep <name-of-the-script>
または一般的に
ps -p "$(<name-of-the-script>)" -o times=
プロセスIDを取得します。
次に、結果を変数に割り当て、必要に応じて頻繁にチェックします。