私は他の世界からUNIXに飛び込み、
while true
do
/someperlscript.pl
done
Perlスクリプト自体には、ターゲットの場所でファイルが変更されたときに実行されるフォルダ/ファイルウォッチャーがあります。
これはwhile true
良い考えですか?そうでなければ、好ましい強力なアプローチは何ですか?
ティア
編集:これはかなりの関心を引き起こすように見えるので、全体的なシナリオは次のとおりです。 Perlスクリプト自体はファイルウォッチャーを使用してディレクトリを監視します。新しいファイルを受信したら(rsync経由で到着)、新しいファイルを選択して処理します。これで、渡されたファイルが破損する可能性があります(ラズベリーパイから尋ねないでください)、時にはプロセスがそれを処理できないことがあります。私たちはまだすべてを知っていないので、その理由を正確にはわかりません。
ただし、何らかの理由でプロセスが失敗した場合は、次のファイルがエラーを引き起こす可能性がある古いファイルとはまったく関係がないため、プロセスを開始して実行して次のファイルを処理したいと思います。
通常、私は一種のキャッチオールを使用し、コード全体を囲み、競合が発生しないようにします。しかし、Perlについてはよくわかりません。
私が理解したように、Supervisordのようなものを使用するのは良い方法です。
答え1
これは、Perlスクリプトがどれだけ早く返されるかによって異なります。すばやく返される場合は、CPUの負荷を防ぐために実行間に少し一時停止を挿入することができます。たとえば、次のようになります。
while true
do
/someperlscript.pl
sleep 1
done
これはまた、スクリプトが見つからない場合や直ちにクラッシュした場合にCPUを大量に使用することを防ぎます。
これらの問題を回避するために、ループはPerlスクリプト自体で最もよく実装されています。
編集する:
競合が発生した場合にPerlスクリプトを再起動する唯一の目的でループを作成するときのより良いアプローチは、それを監視対象サービスとして実装することですが、正確な方法はオペレーティングシステムによって異なります。例:Solaris smf、Linux systemd、またはcronベースの再起動プログラム。
答え2
使用に関する他の回答はinotify
正確ですが、この質問に対する回答ではありません。
プロセスマネージャ(たとえばsupervisord
、、、upstart
またはrunit
)は、サービスの競合を監視および再開するように特別に設計されています。
ディストリビューションにはプロセスマネージャが組み込まれています。
答え3
while true
一般的な「永遠にループ」構造で素晴らしいです。他の回答からわかるように、ループ内部コマンドは機能しないため、ループ本体が空であるか空であるべきではありません。
Linuxを使用している場合は、同様のコマンドを使用してループをより簡単にするinotifywait
ことができます。while
while inotifywait -qqe modify "$DIRECTORY"
do
process_the_directory "$DIRECTORY"
done
ここではinotifywait
、コマンドはファイルシステムイベントが発生するのを待ちます(この場合はディレクトリ内のファイルが書き込まれるとき)。この時点では、ループ本体を正常に終了して実行します。これで待機状態に戻ります。このinotifywait
コマンドは、ディレクトリで何かが起こるのを待つため、ディレクトリを継続的にポーリングするよりもはるかに効率的です。
答え4
Perlスクリプトを永久に実行したいときにwhile構文を使用するのはなぜですか?重大な問題が原因でPerlが失敗すると、同時に起動された新しいPerlスクリプトも同様に重大にクラッシュする可能性があります。続けてお待ちください。
Perlを本当に再起動するには、まずcrontabと実行中のインスタンスを確認するスクリプトを検討してください。これにより、再起動後もスクリプトが起動します。