標準入力および標準出力ストリームのリダイレクト

これまで見てきたプログラムはすべて、stdinおよびstdout、つまり標準入力および標準出力ストリームを介して相互作用していた。readfおよびwritelnなどの入力および出力関数は、デフォルトではこれらのストリームに対して動作する。

これらのストリームを使用する際、標準入力はキーボードから、標準出力は画面に送信されるものと仮定していた。

後続の章では、ファイルを扱うプログラムの記述を開始する。ファイルも標準入力と標準出力ストリームと同様に文字ストリームであるため、stdinstdoutとほぼ同じように使用されることを確認する。

しかし、プログラム内からファイルにアクセスする方法を見る前に、プログラムの標準入力と標準出力をファイルにリダイレクトしたり、他のプログラムにパイプで接続したりする方法について説明したい。既存のプログラムは、ソースコードを変更せずに、画面ではなくファイルに出力するように、またはキーボードではなくファイルから読み込むように変更できる。これらの機能はプログラミング言語と直接関係はないが、ほぼすべての現代のシェルで利用可能な便利なツールだ。

オペレーターを使用して標準出力をファイルにリダイレクトする>

ターミナルからプログラムを開始する際に、コマンドラインの最後に>文字とファイル名を入力すると、そのプログラムの標準出力が指定したファイルにリダイレクトされる。プログラムが標準出力に表示するものはすべて、そのファイルに書き込まれる。

入力から浮動小数点数を読み込み、その数を2倍にし、結果を標準出力に表示するプログラムでこれを試しよう:

import std.stdio;

void main() {
    double number;
    readf(" %s", &number);

    writeln(number * 2);
}
D
stream_redirect.1

プログラムの名前がby_twoの場合、コマンドラインで以下の行のようにプログラムを実行すると、その出力はby_two_result.txtという名前のファイルに書き込まれる。

./by_two > by_two_result.txt
Bash

例えば、ターミナルで1.2と入力すると、結果2.4by_two_result.txtに表示される。(注:このプログラムは"数字を入力しよう"のようなプロンプトを表示しないが、数字の入力を期待している。)

オペレーターを使用してファイルから標準入力をリダイレクトする<

標準出力をリダイレクトする>演算子と同様に、標準入力をリダイレクトする<演算子を使用して、ファイルから標準入力をリダイレクトすることができる。この場合、プログラムはキーボードではなく指定されたファイルから読み込む。

これを試すために、数値の10分の1を計算するプログラムを使用しよう。

import std.stdio;

void main() {
    double number;
    readf(" %s", &number);

    writeln(number / 10);
}
D
stream_redirect.2

ファイルby_two_result.txtがまだ存在し、前回の出力から2.4を含むものと仮定し、新しいプログラムの名前がone_tenthであるとすると、新しいプログラムの標準入力をそのファイルからリダイレクトするには、次の行のようにする:

./one_tenth < by_two_result.txt
Bash

この場合、プログラムはby_two_result.txtから読み込み、結果を0.24としてターミナルに表示する。

両方の標準ストリームをリダイレクトする

><のオペレーターを同時に使用できる:

./one_tenth < by_two_result.txt > one_tenth_result.txt
Bash

この場合、標準入力はby_two_result.txtから読み込まれ、標準出力はone_tenth_result.txtに書き込まれる。

演算子を使用してプログラムをパイプする|

by_two_result.txtは2つのプログラム間の仲介役であることに注意。by_twoはそこに書き込むし、one_tenthはそこから読み込む。

|演算子は、左側のプログラムの標準出力を、右側のプログラムの標準入力に、中間ファイルを使用せずにパイプで送る。例えば、上記の2つのプログラムを次の行のようにパイプでつなぐと、入力の5分の1をまとめて計算する。

./by_two | ./one_tenth
Bash

まず、by_twoは入力から数値を読み込む。(数値の入力を促すメッセージは表示されないが、数値が入力されるまで待機する。)次に、by_twoは結果を標準出力に書き出す。by_twoの結果は、one_tenthの標準入力に表示され、one_tenthはその結果の10分の1を計算して表示する。

演習

複数のプログラムをパイプで接続する:

./one | ./two | ./three
Bash