トップC/C++ > パイプとリダイレクト

パイプとリダイレクト

1.パイプ

パイプ(pipe)とは、あるプログラムの標準出力(stdout)を 別のプログラムの標準入力(stdin)に引き渡す機能である。

例えばあるプログラム foo の出力行数が非常に多いとき

   foo | more
とすれば、先頭から数十行(1画面分)ずつ、表示内容を確認できる。

また、ある処理を二つ以上の処理に分けて、その間をパイプでつなぐようにすれば、 個々のプログラムの独立性は極めて高くなり、 プログラムの開発、デバッグが容易となる。 このパイプはプログラミング言語には依存しないので、C言語でもJavaでも使用可能である。

地図アプリでの使用事例

自作地図アプリ自体はスマホで動くが、そのデータはパソコンで作成している。 データは圧縮されているが、それを処理するプログラム(この例では Java で作られた LandPolygon.class)は 解凍したデータが必要である。

地図データは巨大であり、例えば europe-latest.osm.pbf は 26GB あり、これを解凍すると、500GB 程度になる。 大きなディスク容量が必要となり、ファイルの書き込みに時間がかかり、これを読み込むのにも時間がかかる。

このため、osmconvert や LandPolygon はパイプやリダイレクトの使用を想定して、 標準出力や標準入力が使われる。

下に示すように、osmconvert は解凍したテキストデータを標準出力を書きだす。 LandPolygon はこれを標準入力で受けてテキストデータを受け取る。

ファイルへの書き込みやファイルからの読み込みがないため、 その分、高速に処理ができるし、大きなディスク容量も要らない。

このような用途ではパイプが必須と言える。

osmconvert  d:/downloads/europe-latest.osm.pbf | java -Dfile.encoding=UTF-8 -Xmx5000m LandPolygon -way europe

2.リダイレクト

あるプログラム foo は標準入力からデータを読み込んで処理を行うものであったとき、

   foo < input.txt
とすれば、input.txt の内容がキーボードから入力されたかが如く、処理が実行される。
   foo > output.txt
とすれば、foo の標準出力が画面に表示される代わりに、output.txt に書き込まれる。 次のように、入出力を同時にリダイレクトすることもできる。
   foo < input.txt > output.txt
または
   foo  > output.txt < input.txt

実行前に、何らかの情報が入っていた output.txt に対して

   foo > output.txt
を実行すると、前の内容は消されて、新しい内容が書き込まれる。

これに対して、

   foo >> output.txt
とした場合には、前の内容はそのまま残り、その後ろに foo の今回の出力が追加書込みされる。

fooが標準出力のほかに、標準エラー出力(stderr)を行った場合、 このエラー出力は画面に表示される。

エラー出力を画面ではなく、ファイルにリダイレクトをすることもできるが、UNIXとDOSでは少し異なる。UNIXでは

$ foo >& error.txt
であるが、DOSでは
c:\ foo 2> error.txt
とする。因みに 1> とした場合、標準出力のリダイレクトとなる。

パイプで挙げた例題は、

  c:\tsp>cat parname.txt | lkh
とする代わりに、 次のように、リダイレクトを使う方がシンプルとなる。
  c:\tsp>lkh < parname.txt