リダイレクトとパイプを図示してみた (2)
前回の続きです。今回は、リダイレクトの記号が複数のケースと、パイプを使うケースを説明します。
前回: id:simply-k:20100731:1280607841
次回: id:simply-k:20100802:1280617927
(7) コマンド 1> ファイル 2>&1
2段階に分割して考えます。リダイレクトの記号が複数の場合は、左側から順に考えます。
(7-1) 1> ファイル
1番の出力先(標準出力)をファイルにリダイレクトします。内部的には、ファイルを書き込み用にオープンし、その出力ストリームを1番に結び付けます。*1
(7-2) 2>&1
2番の出力先(標準エラー出力)を1番の出力先(ファイル)にリダイレクトします。内部的には、1番に結びつけられたストリーム(file)を2番に結び付けます。リダイレクトしない場合に標準出力と標準エラー出力に分かれて出力されるデータが、同じファイルに出力されることになります。
なお、標準出力と標準エラー出力をそれぞれ同じファイルにリダイレクトするからといって、「コマンド 1> ファイル 2> ファイル」と書くことは一般にはできません。実行環境によりますが、同じファイルを書き込みモードで2重にオープンしようとしてエラーが発生したり、標準出力のデータが標準エラー出力のデータで上書きされてしまったりします。*2
(8) コマンド 2> ファイル 1>&2
2段階に分割して考えます。リダイレクトの記号が複数の場合は、左側から順に考えます。
(8-2) 1>&2
1番の出力先(標準出力)を2番の出力先(ファイル)にリダイレクトします。内部的には、2番に結びつけられたストリーム(file)を1番に結び付けます。リダイレクトしない場合に標準出力と標準エラー出力に分かれて出力されるデータが、同じファイルに出力されることになります。
(7)の「コマンド 1> ファイル 2>&1」と(8)の「コマンド 2> ファイル 1>&2」は、結果的に同じ処理となります。
(9) コマンド 2>&1 1> ファイル
2段階に分割して考えます。リダイレクトの記号が複数の場合は、左側から順に考えます。
(9-2) 1> ファイル
1番の出力先(標準出力)をファイルにリダイレクトします。内部的には、ファイルを書き込み用にオープンし、その出力ストリームを1番に結び付けます。2番に結び付けられたストリームは変更されません。標準エラー出力に出力されるはずだったデータが標準出力に出力され、標準出力に出力されるはずだったデータがファイルに出力されます。
(9)は、(7)のリダイレクトの順序を入れ替えたものです。図を見てわかるように、(7)と(9)では出力先が異なります。このように、リダイレクトの指定順序によって出力先が変わる場合があるので、注意が必要です。
(10) コマンドA | コマンドB
2段階に分割して考えます。
(10-2) コマンドA | コマンドB
コマンドAとコマンドBが、パイプによって接続されます。コマンドAの標準出力(stdout-a)とコマンドBの標準入力(stdin-b)が1つになったかのように動作します。内部的には、以下の処理が行われます。
- コマンドA側
- パイプを書き込み用にオープンする。
- 標準出力(stdout-a)の代わりにパイプが使われるように、ストリームの結びつきを変更する。
- コマンドB側
- パイプを読み込み用にオープンする。
- 標準入力(stdin-b)の代わりにパイプが使われるように、ストリームの結びつきを変更する。
なお、厳密には「パイプ」、「パイプへの出力ストリーム」、「パイプからの入力ストリーム」の3つは別々に描くべきですが、図の簡略化のため、1つにまとめて「pipe」としています。
(11)以降は次回です。
前回: id:simply-k:20100731:1280607841
次回: id:simply-k:20100802:1280617927