私はBashでパイプ作業をするとき、これについてもう考えていませんでした。しかし、システムコールパイプライン()とフォーク()を使用するいくつかのCコード例を読んで、匿名パイプと名前付きパイプの両方を理解する方法がわかりました。
人々は「Linux/Unixのすべてはファイルだ」という言葉をよく聞いています。パイプが実際にファイルかどうか疑問に思います。接続の一部がパイプファイルに書き込まれ、もう一方がパイプファイルから読み込まれますか?では、匿名パイプのパイプファイルはどこに生成されますか? /tmp、/dev または...?
ただし、名前付きパイプの例では、パイプを使用すると、一時ファイルを明示的に使用するよりも、スペースと時間のパフォーマンスの面で利点があることがわかりました。それはおそらく、パイプの実装にファイルが含まれていないからです。そしてパイプはファイルなどのデータを保存しないようです。だから私はパイプが実際にファイルだと思います。
答え1
パフォーマンスの質問に関してはディスクIOが不要なので、パイプはファイルよりも効率的です。したがって、これは本当ではないかもしれませんcmd1 | cmd2
(RAMディスクまたは他のメモリデバイスで名前付きパイプでサポートされている場合cmd1 > tmpfile; cmd2 < tmpfile
; ただし、名前付きパイプの場合、パイプがいっぱいになると出力がブロックされる可能性があるため、バックグラウンドで実行する必要があります)。結果が必要で、その出力をに送信する必要がある場合は、ディスク読み取りが発生しないようにして並行して実行する必要があります。tmpfile
cmd1
cmd1
cmd2
cmd1 | tee tmpfile | cmd2
cmd1
cmd2
cmd2
名前付きパイプは、多くのプロセスが同じパイプを読み書きする場合に便利です。プログラムが使用する必要があるIOに対してstdin / stdoutを使用するように設計されていない場合にも便利です。文書。ファイルをイタリック体で表示したのは、名前付きパイプがメモリに常駐し、バッファサイズが固定されているため、ストレージの観点から正確にファイルではないためです。ファイルシステム項目(参考用のみ)。その他ものUNIXには、ファイルの代わりにファイルシステムエントリがあります。/dev/null
または他の項目のみを検討してください。/dev
/proc
名前付きパイプと名前なしパイプには固定バッファサイズがあるため、そのパイプに対する読み取り/書き込み操作がブロックされ、読み取り/書き込みプロセスがIOWait状態に入ることがあります。また、メモリバッファから読み込むときにいつEOFを受け取りますか?この行動に関する規則は明確に定義されており、男性でも閲覧できます。
名前付きパイプと名前付きパイプでは実行できないことの1つは、データを照会することです。メモリバッファを使用して実装されるので、これは理解できます。
については"everything in Linux/Unix is a file"
同意しません。名前付きパイプにはファイルシステムエントリがありますが、まさにファイルではありません。名前のないパイプにはファイルシステムエントリはありません(除く/proc
)。ただし、UNIXでは、ほとんどのIO操作は読み取り/書き込み機能を使用して実行されます。ファイル記述子、名前のないパイプ(およびソケット)を含む。私たちはそう言うことができるとは思わない"everything in Linux/Unix is a file"
。しかし、私たちは間違いなくできます"most IO in Linux/Unix is done using a file descriptor"
。
答え2
UNIXの哲学の2つの基本原則は次のとおりです。
- 1つのことをうまく実行する小さなプログラムを作成します。
そして、各プログラムの出力が
他の未知のプログラムの入力になると予想しています。パイプを使用すると、これら2つのデザインベースの効果を活用して、
非常に強力なコマンドチェーンを作成して目的の結果を得ることができます。ファイルに対して機能するほとんどのコマンドラインプログラムは、標準入力(キーボードを介した入力)の入力を許可し、標準出力(
画面に印刷)として出力することもできます。一部のコマンドはパイプ内でのみ機能するように設計されており、ファイルに直接操作することはできません。
たとえば、
tr
次のコマンドは
ls -C | tr 'a-z' 'A-Z'
cmd1 | cmd2
cmd1のSTDOUTを画面ではなくcmd2のSTDINに送信します。
STDERRはパイプを介して渡されません。
つまり、
Pipes is character (|)
コマンドをリンクできます。STDOUTに書き込むすべてのコマンドは、パイプの左側で使用できます。
ls - /etc | less
STDIN から読み出したコマンドはすべてパイプの右側で使用できます。
echo "test print" | lpr
伝統的なパイプは匿名で存在し、プロセスの実行中にのみ持続するという点で「名前はありません」。名前付きパイプはシステムに永続的でプロセス寿命の外に存在し、使用されなくなった場合は削除する必要があります。プロセスは通常、名前付きパイプ(通常はファイルとして表示)に接続され、プロセス間通信(IPC)を実行します。
答え3
他の答えを補うために...
stdin と stdout はファイル記述子であり、ファイルのように読み書きできます。したがって、echo hi | grep hi
echoの標準出力をパイプに置き換え、grepの標準入力をそのパイプのもう一方の端に変更することができます。
答え4
すべてがファイルです。
この文章をあまり文字通り受け入れれば「ファイルだけあり他はありません」という意味で終わるようになります。これは正しい説明ではないので、何ですか?
「すべてがファイルです」と言うとき、すべてがディスクに保存されるわけではありません。私たちは、すべてがファイルのように見え、読むことができ、書くことができると言います。
Unixでは、ファイルまたはファイルではなくファイルを開くとファイルとして扱われます。ただし、すべての操作がすべてのファイルでサポートされるわけではありません。たとえば、一部のファイル(ファイルではない)は検索をサポートしていません。これらのファイルは順次読み書きする必要があります(パイプとソケットも同じです)。
すべてにはファイル名があります(一部のシステムでは、例えばDebian Gnu / Linuxや他の多くのGnu / Linuxなど)。
- 開いているすべてのファイルにはファイル名があります。バラより
/proc/self/fd/…
/dev/tcp
ファイル名を使用してネットワークソケットを開くことができます。cat </dev/tcp/towel.blinkenlights.nl/23