web-dev-qa-db-ja.com

壊れたパイプを回避する方法はありますか?

多数のファイルを含むディレクトリがあります。

./I_am_a_dir_with_many_subdirs/

スクリプト内で、その中のすべてのサブディレクトリを検索し、それらを並べ替えて、bash配列に出力したいと思います。私もです:

SubdirsArray=(`find ./I_am_a_dir_with_many_subdirs/ -maxdepth 2 -mindepth 2 -type d | sort`)

スクリプトを実行すると、次のエラーメッセージが表示されます。

    sort: write failed: standard output: Broken pipe
    sort: write error

これで説明されているように post :おそらくsortは、findがパイプへの書き込みを完了する前に、パイプを実行して閉じます。したがって、findによって開始されたwrite()コマンドは、エラーEPIPE "Broken pipe"を取得し、OSはfindにSIGPIPEを送信します。 SIGPIPEがfindに到達する前に、エラーメッセージを出力してから、SIGPIPEを取得して終了します。

質問:

  1. それで、私のSubdirsArrayには何が含まれていますか? findが見つけたが、sortがソートされていないサブディレクトリ?

  2. もしそうなら、壊れたパイプでこの問題を回避する方法は何でしょうか?検索結果を一時ファイルに書き込んでから、並べ替えで読み取りますか?

    非対話型シェル内で発生した場合、なぜ「心配する必要もない」のかわかりません。なぜですか。私のSubdirsArrayにはソートされていないものが含まれており、スクリプトのさらにその要素はソートされていると思いますか?!

  3. 2つのエラーメッセージが表示されます。

    sort: write failed: standard output: Broken pipe
    sort: write error
    

この スレッド では、sortの一時ディレクトリにすべての入力をソートするのに十分なスペースがないことが示唆されています。しかし、それは、その種が発見から何かを得たという意味ではありませんか?!?混乱している…とにかく使ってみた

SubdirsArray=(`find ./I_am_a_dir_with_many_subdirs/ -maxdepth 2 -mindepth 2 -type d | sort -T /home/temp_dir`)

しかし、それは役に立ちませんでした。

P.S.

重要かどうかはわかりませんが、マルチプロセッサスクリプトでfind|sortを使用しています。複数のプロセッサがサブシェルで同じコマンドを同時に実行します。

2
user1541776
sort: write failed: standard output: Broken pipe

問題はfindsortの間ではありません。 sortにはoutputに問題があります。これは、シェルが変数内の長いリストを読み取ろうとしないことを意味します。

入力をwhile read…で処理し、複数回必要な場合は一時ファイルに保存する必要があります。追加の利点として、これは改行でのみ分割されるため、バッククォートアプローチでは処理されないスペースを含むファイル名を正しく処理します。

残念ながら、結果をどのように使用したいかはわかりません。正確に書き直す方法はわかりません。

配列はPOSIXシェル仕様の一部ではなく、bashよりも著しく高速なシェルがありますが、それらはありません。そのため、私を含む多くの人々は、スクリプトでそれらを使用することをしばしば避けています。

2
Jan Hudec