Cronは、STDERRに書かれたすべての内容がカーネル(または不明なcron)にSIGPIPEを受け取るように送信されたすべてのプログラムを実行します。この機能はどのように機能しますか? cronはSIGPIPEを送信しますか、それともカーネルを送信しますか? cronで何かを実行しないで、どのように同じ効果を得ることができますか?誰かがPerlスクリプトを実行する方法を教えてもらえますか?
#!/usr/bin/env perl
warn 'foo';
print "bar;
STDERRに「foo」を書き込もうとし、「bar」を書いていないときにSIGPIPEを受け取りますか? Perlが終了してシェル変数$?
が返されるのを見たいです255
。
答え1
STDERRをパイプの書き込み側にリダイレクトし、読み取り側を閉じてこれを行うことができます。
#!/usr/bin/env perl
pipe R,STDERR;
close R;
warn 'foo';
print "bar";
答え2
「この機能はどのように機能しますか?」
あなたが説明するのは実際の機能ではなく、誤解による機能障害です。 SIGPIPEを送信するのはcronではなく使用する方法です。
デフォルトでは、cronはプロセスのstdoutとstderrをcrontabの所有者に電子メールで送信します。メールを送信(注man cron
:MTAがインストールされていない場合、出力がリダイレクトされない限り削除されます。)これを行うには、プロセスが完了するまで待つ必要があります。ただし、以下を使用してプロセスをバックグラウンドに配置する場合&
:
* * * * * /bin/someprogram &
プログラムがstdoutまたはstderrに書き込もうとすると、パイプが破損しているため(読み込み終了が閉じる)SIGPIPEを受け取ります。[これは、MTAが欠落していて出力が多い場合、以前のcronの非バックグラウンドプロセスでも発生する可能性があります。]
だから私はあなたのcrontabに次のようなものがあると思います。
* * * * * /bin/someprogram > log.file &
これは、stdoutがファイルにリダイレクトされますが、stderrパイプがまだ破損していることを意味します。これは間違った結論につながります。「cronは、STDERRに書かれたすべての内容が…SIGPIPEになるように送信されたすべてのプログラムを実行します。」。
&
背景を削除するかstderrをリダイレクトしてcrontabを変更することもできます。
* * * * * /bin/someprogram 1>&2&> log.file &
欲しいならWRTはqqxが言ったように、これを直接複製します。パイプの一端を閉じて書いてください。