パイプ生産者は、パイプ消費者に「ファイルの終わり」に達したことをどのように伝えますか? (名前のないパイプ、名前のないパイプ)

パイプ生産者は、パイプ消費者に「ファイルの終わり」に達したことをどのように伝えますか? (名前のないパイプ、名前のないパイプ)

必要なアプリケーションがあります。生産者ファイル名の送信消費者、そしてあります生産者指示する消費者最後のファイル名が転送されたときファイルの終わり達成。

簡略化のため、次の例では生産者 デモンストレーションにはとを使用しechoprintfデモには消費者を使用しますcat。私は「ここにファイルを保存する」方法を推論しようとしましたが、成功しませんでした<<EOFプロデューサーラッパー(そのようなものが存在する場合)ファイルの終わり。有効な場合は、出力からフィルタリングcatする必要があります。EOF

例1)

入力する

{
echo "Hello World!" 
printf '\x04' 
echo "EOF"
} <<EOF |\
cat

出力

bash: warning: here-document at line 146 delimited by end-of-file (wanted `EOF')
Hello World!
EOF

例2)

入力する

{ 
echo "Hello World!" 
printf '\x04' 
echo "EOF"
} |\
cat <<EOF

出力

bash: warning: here-document at line 153 delimited by end-of-file (wanted `EOF')

区切り文字を表示するための「ここにファイルを保存する」方法は、静的テキストでのみ機能し、動的に生成されたテキストでは機能しないことは正しいですか?

--実用的なアプリケーション--

inotifywait -m --format '%w%f' /Dir |  <consumer>

コンシューマは /Dir ディレクトリにファイルが書き込まれるのを待っています。 「/Dir/EOF」ファイルが作成されると、コンシューマは次のようにシェルスクリプトを作成して論理ファイルの終了条件を検出できます。

inotifywait -m --format '%w%f' /Dir |<</Dir/EOF  <consumer>

——ザイルズの回答に対する回答——

理論的に可能ですか?

cat <<EOF
hello
world
EOF

〜のように

SpecialSymbol="EOF"
{
    echo hello
    echo world
    echo $SpecialSymbol
} |\
while read Line; do 
  if [[ $Line == $SpecialSymbol ]]
    break
  else 
    echo $Line
  fi
done |\
cat

理論的には、たぶん私の言葉は「既存の使用パターンをサポートし、以前に違法な構文を持つ追加使用パターンのみを有効にしますか?」- 既存の法律および規制が損なわれないことを意味します。

ベストアンサー1

パイプの場合、すべてのプロデューサがパイプのファイル記述子を閉じ、消費者がすべてのデータを読み取った後、消費者はファイルの終わりを表示します。

したがって:

{
  echo foo
  echo bar
} | cat

catecho2番目のエントリが終了し、合計がcat読み込まれると、ファイルの終わりが表示されます。もうやることはありません。foo\nbar\n

ただし、覚えておくべきことは、パイプの左側のコマンドの一部がバックグラウンドプロセスを開始すると、そのバックグラウンドプロセスがパイプのfd(stdout)を継承するため、そのcatプロセスも終了するまでeofまたは終了が表示されないことです。標準出力。良い:

{
  echo foo
  sleep 10 &
  echo bar
} | cat

cat返品なしで10秒経過したことがわかります。

sleepここでstdoutを別のものにリダイレクトできます。たとえば、/dev/null対応する(非)出力が次に供給されることを望まない場合cat

{
  echo foo
  sleep 10 > /dev/null &
  echo bar
} | cat

左側のサブシェルで最後のコマンドを実行する前にパイプの書き込み端を閉じるには、stdoutを|閉じるか、中央のサブシェルにリダイレクトを使用できますexec。たとえば、次のようになります。

{
  echo foo
  exec > /dev/null
  sleep 10
} | (cat; echo "cat is now gone")

ただし、ほとんどのシェルはコマンドに加えてこのサブシェルを待ちますcat。したがって、読んだcat is now gone直後に表示できますが、fooパイプライン全体が完了するまで10秒待つ必要があります。もちろん、上記の例では、次のように書く方が合理的です。

echo foo | cat
sleep 10

<<ANYTHING...content...ANYTHINGコマンドの標準入力を以下を含むファイルにするここのドキュメントです。コンテンツ。そこには役に立たない。\4は、端末から読み取られたときに端末装置に格納されているデータがデータを読み取るアプリケーションにフラッシュされるバイトです(データがない場合はread()0が返され、ファイルの終わりを示します)。繰り返しますが、ここでは役に立ちません。

おすすめ記事