こんばんは、
以下は、スクリプトで使用しているコードの一部です。 SSHセッションからの起動は正常に機能しますが、cron経由で実行すると、画面に壊れたパイプエラーが表示されます。
SSH経由でそれを再現できません。
コード:
IP=$(sort --random-sort /root/ips.csv | head -n 1); nc -zv -w 2 $IP 443 2>&1 | grep succeeded >> outfile
画面のエラー:
sort: write failed: standard output; Broken pipe
sort: write error
ヒント/ポインタはありますか?
ありがとうございました!
head
は、最初の行を処理した後に終了すると、パイプのもう一方の端を閉じて終了します。 sort
はまだ書き込みを試みている可能性があり、閉じたパイプまたはソケットに書き込むとEPIPEエラーが返されます。ただし、シグナルが無視または処理されない限り、SIGPIPEシグナルが発生し、プロセスが強制終了されます。シグナルが無視されると、sort
はエラーを確認し、エラーを出して終了します。ただし、信号が無視されない場合は、エラーメッセージを残さずに信号が停止します。
シグナルの無視は子プロセスに継承されるため、シェルから制御できます。
$ trap - PIPE # set default action for signal
$ sort bigfile | head -1 > /dev/null # no error message
$ trap "" PIPE # ignore the signal
$ sort bigfile | head -1 > /dev/null
sort: write failed: standard output: Broken pipe
sort: write error
Systemdとの関係がない限り、なぜcronがシグナルを無視するのかわかりません。 これにより、デフォルトでSIGPIPEが無視されるようになります :
ただし、これは通常のデーモンにはあまり役立ちません。デーモンに優れた便利な実行環境を提供するため、これをオフにします。もちろん、シェルなどはこれを再びオンにする必要があります。
私のシステムでは、/lib/systemd/system/cron.service
はIgnoreSIGPIPE=false
を設定して、cronのデフォルトを明示的に取り消します。