存在するこの回答一番下では、Gillesはコマンドに複数の出力または入力がある可能性があると述べています。
はい、合計を入力としてcat foo bar | something
使用して出力として使用する場合がありますが、実際にはそういう意味ではないようです。foo
bar
tee
どのようにプログラムに複数の入力または出力がありますか?
答え1
このcat foo bar
例は私が意図したものではありません。cat
一度に1つの入力と1つの出力しかありません。
tee
たとえば、次のようになります。すべての引数と標準出力に出力します。と同じタイプのASCIIアートを使用してください。私の以前の答え、tee foo bar
端末で実行したときの様子です。
+------------------+
| tee |
===|<stdin | +------------+
→ | | | terminal |
| stdout>|=========|<input |
| | → ##==|< |
| | || +------------+
| stderr>|=====##
| | →
| | +-------------+
| 3>|=======|> file "foo" |
| | → +-------------+
| | +-------------+
| 4>|=======|> file "bar" |
| | → +-------------+
| |
+------------------+
この例では、tee
「有用な」出力は3つのチャンネル、つまり端末(標準出力が接続されている場所)と2つのファイルに送信されます。また、tee
追加のエラー出力チャネルがあります。
プログラムには通常、チャンネルとして識別される3つの入力/出力チャンネルがあります。ファイル記述子数字:
- 標準入力(単にstdin、ファイル記述子0)。
- 標準出力(stdout、ファイル記述子1と呼ばれる)
- 標準エラー(単にstderr、ファイル記述子番号2)。
ファイル記述子0、1、2の目的は、単にルールの問題です。プログラムがファイル記述子 0 に書き込んだり、記述子 1 と 2 から読み取れないように強制することはありませんが、ほとんど普遍的に従う規則です。
端末でプログラムを実行する場合、ファイル記述子 0、1、2 は、リダイレクトされない限り、最初に端末に接続されます。他のファイル記述子は最初に閉じられ、プログラムが別のファイルを開くときに使用されます。
特に、すべてのコマンドには、標準出力(コマンドのペイロード、「有用な」出力)と標準エラー(エラーまたは情報メッセージ)の2つの出力があります。
シェル(command1 | command2 | command3 | …
)のパイプは、各コマンドの標準出力を次のコマンドの標準入力に接続します。すべてのコマンドの標準エラーは、リダイレクトされない限り端末に送信されます。
シェルは、他のファイル記述子をリダイレクトする方法を提供します。標準エラーが発生したかリダイレクトされている可能性2>&1
があります。2>file
バラより
追加のファイル記述子はいつ使用されますか?別の投稿は、他のファイル記述子の操作例へのリンクです。
機能豊富なシェルはまた、以下を提供します。プロセスの交換コマンドごとに単一入力と単一出力を持つ線形パイプラインに制限されないように、パイプラインコマンドのファイルリダイレクトを一般化します。
ファイルを開かない限り、2 より大きいファイル記述子にアクセスしようとするコマンドはほとんどありません。ファイルを開くと、無料のファイル記述子が選択され、その番号がアプリケーションに返されます。たとえば、GnuPGは標準入力から暗号化/復号化/署名/検証のためにデータを読み取り、結果を標準出力に書き込むことを期待しています。このオプションを使用して、他のファイル記述子からパスワードを読み取るように指示できます--passphrase-fd
。 GnuPGには他のファイル記述子のステータスデータを報告するオプションもあり、stdoutにペイロードを出力し、stderrにエラーメッセージを出力し、他のファイル記述子に関するステータス情報を取得できます。以下は、パイプされたコマンドの出力をパスワードとして使用する例です。
echo fjbeqsvfu | rot13 | gpg -d --passphrase-fd=3 3<&0 <file.encrypted >file.plaintext
答え2
コマンドは複数の出力ストリームを持つことができます。ファイルやソケットに書き込むことを意味するものではありません。ほとんどのGNUツール(例grep
:)は、エラーをstderrとして印刷し、予想される出力をstdoutとして印刷することを検討してください。どちらもインタラクティブシェル(2>&1)にマージされますが、それでも別々に処理できます。プログラムまたはコードブロックがサポートされている場合は、追加のファイル記述子を使用できるため、ここでは終了しません。
設計された例:
{
grep NORMAL log.txt
grep WARN log.txt 1>&3
grep ERROR log.txt 1>&4
} 1> normals.txt 3> warnings.txt 4> errors.txt # 2>/dev/null
答え3
はい。たとえば、cat foo bar | less
2つの入力(file fooとfile bar)が与えられ、両方ともlessとして出力されます。vim foo*
fooで始まるすべてのファイルはvimとして出力されます。各ファイルを表示した後、 :n (または変更した場合 :wn) を使用して次の出力に切り替えることができます。私はギルスがそれをよく説明したと思います。パイプ(|)を使用すると、あるコマンドの出力を取得し、別のコマンドに入力して結果を印刷します。これはマルチ出力の別の例です。