リダイレクト
先日 リダイレクトとパイプについてちょろっと書いた。そのとき気になった部分を調べた。
気になったことは、リダイレクトを使った場合と、パイプを使った場合でプログラム内部で処理の違いが出てくるのか?ということ。とくに、ファイル位置の操作に関して。
準備
テストコード (a.c)
#include <stdio.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char **argv) { char buf[1024]; ssize_t rsize; do { memset(buf, 0, sizeof(buf)); rsize = read(0, buf, sizeof(buf)); printf("read: [%s]\n", buf); // 読み込んだ分だけファイル位置を戻す→無限ループ if (lseek(0, (off_t)(-1 * rsize), SEEK_CUR) == -1) { printf("Error: %s\n", errno == ESPIPE ? "ESPIPE" : "Other"); } } while (rsize > 0); return 0; }
入力ファイル (input.txt)
aiueo
実行
リダイレクトの場合
% ./a.out < input.txt read: [aiueo ] read: [aiueo ] . . . 繰り返し
パイプの場合
% cat input.txt | ./a.out read: [aiueo ] Error: ESPIPE read: [] Error: ESPIPE
まとめ
リダイレクトは、lseek でファイル位置を操作できた。
パイプは lseek でファイル位置を操作しようとするとエラーが発生した。
http://www.linux.or.jp/JM/html/LDP_man-pages/man2/lseek.2.html によると
とのこと。そりゃそうだよね。パイプとかソケットで通信していて、過去に受信したデータを読もうとするなんて。
まあ、こうなるのではという予想を確かめるための調査だったので、驚くようなことはなかった。
ところで、これを書くまでリダイレクトって用語の理解を間違えていたみたい。今まで、リダイレクトっていうと「>」「>>」「<」を思い浮かべていたけど、パイプももリダイレクトだね。でもやっぱり、リダイレクトっていったら先に挙げた3つかな。
パイプ ⊂ リダイレクト って感じ?
そういえば、ヒアドキュメントってのもあったな、全然使わないから忘れてた...