web-dev-qa-db-ja.com

ソート:書き込みに失敗しました|壊れたパイプ

こんばんは、

以下は、スクリプトで使用しているコードの一部です。 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

ヒント/ポインタはありますか?

ありがとうございました!

7
t988GF

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.serviceIgnoreSIGPIPE=falseを設定して、cronのデフォルトを明示的に取り消します。

8
ilkkachu