ソート:書き込み失敗|

ソート:書き込み失敗|

おやすみなさい、

以下は私のスクリプトで使用するコードです。 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

どのようなヒントやアドバイスがありますか?

ありがとうございます!

ベストアンサー1

最初の行処理が終了すると、headパイプのもう一方の端を閉じて終了します。sort引き続き書き込みを試みる可能性があり、閉じたパイプまたはソケットに書き込むとEPIPEエラーが返されます。ただし、SIGPIPE シグナルも発生し、シグナルを無視または処理しない限り、プロセスは終了します。シグナルを無視するとsortエラーが表示され、文句を言うと終了します。この信号を無視しないと、sortあなたは死にます。

私達は利用できますtrap組み込みシェルの信号は無視され、エラーが発生します。

$ trap "" PIPE
$ sort bigfile | head -1 > /dev/null 
sort: write failed: standard output: Broken pipe
sort: write error

しかし残念ながら私たちはできないtrap信号を無視することなく、次のような望ましい動作を得るために使用されます。POSIXの要件これは非対話型シェル(スクリプト)では許可されていません。対話型シェルを許可しますが、Bashはtrapこの場合もそうしません。

テストするには:

sh$ trap '' PIPE                     # ignore the signal    
sh$ PS1='another$ ' bash             # run another shell
another$ trap - PIPE                 # try to reset the signal
                                     # it doesn't work
another$ sort bigfile |head -1 > /dev/null
sort: write failed: 'standard output': Broken pipe
sort: write error

代わりに、Perl one-linerなどの外部ツールを使用してスクリプトやコマンドを実行できます。信号は無視されません(sortここでは自動的に終了します)。

another$ perl -e '$SIG{PIPE}="DEFAULT"; exec "@ARGV"' \
         'sort bigfile |head -1' > /dev/null 
another$ 

あなたのクローンの状況は、その理由が体系化されている可能性があります。明らかに、SIGPIPEはデフォルトでは無視されます。、言及:

[SIGPIPE]は通常のデーモンにはあまり役に立ちません。デーモンに便利で良い実行環境を提供しようとすると、この機能はオフになります。もちろん、シェルや他のものをもう一度開く必要があります。

もちろんこれも言及されていますがドキュメント(systemd.exec)から:

IgnoreSIGPIPE=
ブールパラメータを使用します。 trueの場合、実行プロセスはSIGPIPEを無視します。 SIGPIPE は通常シェルパイプでのみ有用であるため、デフォルトは true です。

私のDebianシステムでは/lib/systemd/system/cron.service 明示的な設定IgnoreSIGPIPE=false、cronのシステムデフォルトを元に戻します。これがあなたの場合に役立つことを確認したいかもしれません。

おすすめ記事