プロセス置換の文脈におけるI/Oリダイレクトの理解

プロセス置換の文脈におけるI/Oリダイレクトの理解

GNU bash バージョン 4.3.11(1) リリース (x86_64-pc-linux-gnu) を実行します。

よくわかりません。プロセスの交換(ProcSub)I / O処理と関連する速度の問題に興味があるユーザーの観点から。 ProcSubを使ってスクリプトを書いているので、ファイル記述子0,1,2のアイデアはある程度ありますが、それはすべてです。次のような良い記事を読んだ。[1]そしてその他。たとえば、ウィキペディア[2][サム]、後者は次のように言います。「プロセス置換は、あるプロセス(またはプロセス)の出力(FD 1および/または2)を別のプロセスのstdin(FD 0)に供給します。。最も単純な定義と1つのプロセスしかないと、名前のない単純なパイプとは大きく異なっていないようです。

これを調べるためにteeI / Oの観点から始めましたが、それ自体は興味深いものです。
tee餌を与えることが許される「stdinからstdoutへ、そして引数として提供されたすべてのファイル」。だから:

$ for i in 1 2 3; do (( j=i+10 )); printf "%d\n" $j > file_$i; done
# so each file in file_{1,2,3} contains the numeral in its name + 10.
$ cat file_{1,2,3} | tee file_4
11
12
13
$ cat file_4
11
12
13

明らかに、私はデータが私の画面ala Matrixを埋めるのを見ることに興味がありません。したがって、次のような場合:

1)パイプを追加してshasum出力をリダイレクトしました。

$ cat file_{1,2,3} | tee file_4 | shasum -a 256 > file_4.sha256
$ 

上記の定期船出口静かに、file_4は前(上)と同じで、file_4.sha256には計算されたSHA256の合計が含まれています。

上記は、中間I / Oを理解しようとしている私の問題を説明するための例です。私のアイデンティティの結論は、teecmdの出力がcatfile_4に格納され、通常stdoutに送信されるコピーは実際にstdoutに送信されませんshasum
尋ねる:これは完全に正しいことですか?

2)ProcSubを使って同じことを試しました。

$ cat file_{1,2,3} | tee file_4 >(shasum -a 256 > file_4.sha256)
11
12
13
$ 

-> stdoutリダイレクトなしでFD 1に送信されたものはありますかtee

尋ねる:ProcSubがi / oで何をしているのか、そうでないのかは明らかではなく(明らかにこの場合はi / oには影響しません)、そのメカニズムの説明を使用できます。

三)ProcSubを使用し、最終的なstdoutをfile_4にリダイレクトしてみました。

$ cat file_{1,2,3} | tee >(shasum -a 256 > file_4.sha256) > file_4
$ 

今回は気の利いた言葉が静かに出席しています。

尋ねる:したがって、一般的な質問は次のとおりです。上記の3つのケース(または少なくとも2番目と3番目の場合)について、i / oはどのように処理されますか? I / O用語には顕著な違いがありますが(最終的な標準出力のみを見てください)、異なるI / Oプロセスが原因でディスプレイに同じ最終結果が表示されることがあります。テキサス。

ベストアンサー1

このイディオムは>(...)単に(口語で)次のことを意味します。名前ファイル"。

これは「ファイル名」として機能します(一種のすべてがすぐに明確になります)。

$ echo <(date)
/proc/self/fd/11

またはオペレーティングシステムの他の番号/名前。しかし、echoは次のように名前を印刷します。

$ echo ProcSubs11
ProcSubs11

ラベルがProcSubs11のファイルがある場合は、次のこともできます。

$ cat ProcSubs11
contents_of_file_ProcSubs11

あなたも同じことができます:

$ cat <(date)
Fri Jan 15 21:25:18 UTC 2016

違いは、「プロセスの置き換え」の実際の名前が「見えない」であり、詳細がリンクのすべての痛みを伴う詳細で説明されているように、単純なファイルを読むよりもはるかに長いことです。Bashでプロセス交換を実装する方法は?


それでは、プロジェクトを見てみましょう。

質問1

...名前のない単純なパイプと動作方法が変わらないようです...

unnamed pipeまあ、「手続き型置換」はあなたが提供したものに基づいています。最初のリンク状態:

  1. Bashプロセスは、後で作成される2つのプロセス間の通信に使用される名前のないパイプを生成します。

違いは、リンクに記載されている〜6つのステップがすべて1つの>(...)慣用語に縮小されることです。に書く<(...)そして次から読む

そして、接続(パイプ)にもファイルと同じ名前があると言えます。名前はユーザーに隠されているだけです(/proc/self/fd/11最初に示すように)。

実施例1

1)パイプを追加し、shasum出力のリダイレクトを追加しました。

$ cat file_{1,2,3} | tee file_4 | shasum -a 256 > file_4.sha256

そこには「プロセスの置き換え」はありませんが(後で)tee受け取った内容をstdinファイルに転送(書き込む)という点は注目に値します。file_4 そしてにも同じstdin内容を送信しますstdout。 (この場合)shasumが作成されたパイプに接続することが発生します。

簡単に言えば、一般人の観点から、teeはとstdinにコピーされます。file_4shasum

実施例2

2) ProcSubを使って同じことを試しました。

$ cat file_{1,2,3} | tee file_4 >(shasum -a 256 > file_4.sha256)

この例を説明するために、上記の説明を(一般の用語で)再利用します。

Tシャツは、およびのstdin3つの要素にコピーされます。file_4shasumstdout

なぜ? 。これが>(...)ファイル名であることを覚えておいて、それを一行にしてみましょう。

$ cat file_{1,2,3} | tee file_4 /proc/self/fd/11

teeは両方のファイルに入力を提供file_4shasum(「プロセスの置き換え」を介して)、stdoutteeはteeまだデフォルトの場所であるコンソールに接続されています。これがコンソールに数字が表示される理由です。

この例を次のものとまったく同じにするには1)、私達はできます:

$ cat file_{1,2,3} | tee file_4 > /proc/self/fd/11  ### note the added `>`

これは(はい、>および間にスペースを使用する必要があります。>(

$ cat file_{1,2,3} | tee file_4 > >(shasum -a 256 > file_4.sha256)

これはtee標準出力を「プロセスの交換」にリダイレクトします。

質問3

Q:一般的な質問は次のとおりです。 I/O は上記の 3 つの状況をどのように処理しますか?

私はこの3つのケースを説明したと思います。不明な場合はコメントを残してください。

質問4(コメントに質問を編集して追加してください)

3番目のケース<(...)構文が機能しない理由

(素人の観点から)挿入できないのでオスソケットにオス端子プラグ

<(...) イディオムは「プロセス置換」の内部から読み取られるため、stdin外部コマンドに挿入する必要がある「出力」を提供します。外部コマンドが(同様の)要素teeに接続しようとしています。stdoutしたがって、このペアは一致できません。

重要メモ: このコマンドはcat両方のコマンドが同じ出力を提供するため、プロセスの交換に適用されると、一部の詳細が隠されます。

$ cat   <(date)
$ cat < <(date)

すべてが正確ですが、誤解を招く方程式から結論を導くのは間違っています。

おすすめ記事