複雑すぎてbash関数として表現できないプログラムを作成するためにgolangを使用します。プログラムはstdinを1行ずつ読み取り、変更された出力をstdoutに書き込みます。
Stdinアプローチのすべての行でこの反復を行う場合の問題は、早期に終了しないことです。たとえば、次のコマンドは、10行だけでなくすべての行を処理します。
cat largefile | custom-program | head -n 10
ネイティブUNIXアプリケーションはどのようにして早期に終了することができますか?また、カスタムスクリプトで同じことを行うにはどうすればよいですか?
yes | head
では、yes
は、次にパイプのもう一方の端が閉じられた後にラインを書き込むときに(head
が存在する場合)、SIGPIPEシグナルによって終了します。
に:
(seq 20; sleep 10; seq 10) | head
サブシェルと子は、最初の20行をパイプに書き込むことができ(パイプバッファーに収まるように)、その後、無傷で10秒間スリープします。その間、head
は消滅しますが、サブシェルがパイプにさらに行を書き込んだ場合にのみ、パイプが強制終了されます。
head
が返された後に初めてパイプに何かを書き込むのではなく、head
でbash
を使用してコマンドを強制終了したい場合は、次のようにできます。
{ head; kill "$!"; } < <(exec custom-program < large-file)
(bash
は、たまたまプロセス置換のpidを$!
に格納します)。
より移植性の高いアプローチについては、(= /// =)Grepが一致を見つけた後に終了するのが遅いですか? 、または 出力を制限して、信号13 を回避してくださいfind
に適用されます。
または、逆の場合 同様のQ&A に対するこの回答(run_under_watch
関数)は、そのstdinパイプが壊れます。