おやすみなさい、
以下は私のスクリプトで使用するコードです。 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のシステムデフォルトを元に戻します。これがあなたの場合に役立つことを確認したいかもしれません。