5 パイプとリダイレクション

コマンドプロンプトには、 Unix にもある「パイプ」と「リダイレクション」という仕組みが用意されていて、 コマンドとファイルとのデータのやりとり、データファイルの加工、 コマンド間のデータの受け渡しなどが行えるようになっています。 本節では、そのパイプとリダイレクションの概要を説明します。

コマンドプロンプト上で利用できる dir や date のような非ウィンドウソフトは、 コマンドプロンプトのウィンドウ画面上に出力を表示します。 また、set /p のようなコマンドはキーボードから入力をもらいます。 これらの出力、入力は、

と呼ばれています。 C 言語で言えば、printf() や putchar() 等の関数は標準出力への出力を行い、 scanf() や getchar() 等は標準入力から入力をもらう関数です。

この標準出力、標準入力は、 コマンドプロンプトの リダイレクションの機能を利用すれば、 それらを (コマンド毎に) ファイルに切り替えることができます。 コマンドへの標準入力をファイルへ切り替えるには、 コマンド (やオプションパラメータ) の後ろに入力リダイレクション


< [ファイル名]
を追加します。 これは、対話的に入力が必要なコマンドへの固定入力を自動化するのに利用できます。

コマンドの標準出力をファイルに切り替えるには、 コマンド (やオプションパラメータ) の後ろに出力リダイレクション


> [ファイル名]
を追加します。これはコマンドの出力を保存するのに使えます。

入力も出力もファイルに切り替えるには、コマンドの後ろに


< [ファイル1] > [ファイル2]
を追加します。この場合、 ファイル 1 とファイル 2 は別な名前でないと問題が起こるでしょう。 なお、この指定の順は逆でもいいようです。

例えば、


> echo abc > f1.dat
(先頭の > はプロンプト) とすると画面には何も表示されず、 「abc」(と最後に改行) だけが書かれたテキストファイル f1.dat が作られます。 さらに、

> set /p s=リダイレクトテスト < f1.dat
とすれば、入力待ちにはならず直ちに set コマンドが終了し、 環境変数 sabc という文字列が代入されます。

出力リダイレクションには、もう 1 つ、追加出力の


>> [ファイル名]
という形式もあります。 これは、指定したファイルが存在しない場合は > と同じで そのファイルが新規に作られるのですが、 指定したファイルが既に存在する場合は、 となります。

一方、パイプ は、コマンドの標準出力を、 そのまま別のコマンドの標準入力として渡すときに使います。 記号は | です。例えば、


> comA | comB
とすると、コマンド comA と comB の両方が起動され、 comA の標準出力が、そのまま comB の標準入力に流されます。 これと同じことはリダイレクションを用いて、

> comA > f1.dat
> comB < f1.dat
としても行えるのですが、パイプの方が 1 行で済みますし、 中間ファイル f1.dat のようなものを必要としません。 しかもパイプは多段階につなぐことも可能で、例えば

> comA | comB | comC
とすれば、コマンド comA,comB,comC が起動され、 comA の標準出力が comB の標準入力として渡され、 その comB の標準出力が comC の標準入力として 渡されることになります。 これとリダイレクションを組み合せることも可能で、例えば、

> comA < f1.dat | comB | comC > f2.dat
とすると、f1.dat に対する comA の処理の結果が comB に、 その処理の結果が comC に渡され、 その結果が f2.dat として保存されることになります。

標準入力からデータをもらって、 標準出力にその処理結果を書き出すソフトを フィルタ と呼びますが、 この例からもわかるように、 パイプはフィルタを組み合わせてデータを加工するのに向いている仕組みです。 一つ一つのフィルタが単一の機能しかなくても、 複数のフィルタを組み合わせることで、 流れ作業的にデータの複雑な加工処理が行えます。

MS-Windows に用意されている使えそうなフィルタには、

などがあります。他にも、リダイレクトやパイプに関連の深いコマンドとして、

more, type, copy, echo
などがあり、これらについては 7 節で説明しますが、 MS-Windows に標準的に用意されているフィルタはそれほど多くはありません。 C 言語が使えるなら、必要なものを自作するのもいいでしょう。

次に、パイプやリダイレクションと関係が深い 2 つの特別な疑似ファイル (デバイスファイル) connul について説明します。 これらは入力、出力の両方に使えますが、いずれも定義済みのファイルで、 よって逆にこの名前のファイルを作ることはできません。 これらの入力、出力は表 2 のようになっています。

表 2: con と nul
  入力 出力
con 標準入力 標準出力
nul なし なし


例えば、copy コマンドは

> copy fileA fileB
でファイル fileA と同じ内容の fileB を作るコマンドですが、

> copy con fileB
とすると、コピー元のファイルが標準入力なのでキーボードからの入力待ちとなり、 その後キーボードで入力したものが直接 fileB に保存されます。 この場合入力を終了するには、Ctrl-Z を入力します。

一方、nul は入力も出力も何もしない疑似ファイルで、 例えば 4.4 節で見たように、


> comA > nul
として、コマンド comA の標準出力を消すことができますし、

> copy nul fileA
とすれば、サイズ 0 のファイル fileA を作ることができます。

なお、コマンドの出力先は標準出力以外にもうひとつ、 標準エラー出力 (stderr) と呼ばれるものがあり、 ここへの出力は > ではリダイレクトすることができず、 普通は常に画面に表示されます。 コマンドのエラーメッセージなどはここに出力されることが多いので、 それは > nul で消すことはできません。 標準エラー出力をリダイレクトする場合は、2> を用います。 例えば、type コマンドで fileA と fileB を連結して fileC を作る場合、


> type fileA fileB > fileC
とすると、type コマンドは fileA, fileB の名前を標準エラー出力に表示しますが、

> type fileA fileB > fileC 2> nul
とすれば、それも出なくなります。 ただし、2> の間にスペースを開けてはいけません。

竹野茂治@新潟工科大学
2014年5月2日