- ベストアンサー
STDIN に関わる動作の違いについて
幾つかのホストでPerl を使っているのですが STDIN の回りで動作に違いがあり困っています。 test.pl ----- #!/hogehoge/perl print -s STDIN; ----- $ echo 'abcde' | ./test.pl とした場合に、返ってくる結果が違っており 困っております。 この違いは、どこから来るのでしょうか? v5.8.2 built for i386-linux-thread-multi では「0」となりますし v5.8.2 built for i686-linux や version 5.005_03 built for i386-linux では「6」となります v5.8.2 built for i386-linux-thread-multi の時の動作がおかしいようなのですが.... ご教示いただければと思います。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
> パイプからの標準入力がない場合には > 最初の行で標準入力からの入力待ちになってしまい なるほど、考えていませんでした。 で、回避方法を考えていたのですが、若干変則的ですが、次のような方法があるかと思います。 unless(-t STDIN){ print "STDIN"; } else{ print "NO STDIN"; } -t演算子は、ハンドルがttyにオープンされているかどうかをテストします。(引数を省略するとSTDINを調べるので、省略してもOK。)パイプを使用した場合、STDINはttyに結びつけられていないはずなので、上記のようにttyに結びつけられていない場合はパイプ、そうでなければスタンドアロンと判断出来ます。
その他の回答 (2)
- hikomin
- ベストアンサー率63% (40/63)
なるほど、パイプで入力されている場合に処理を変えたいと…。確かにファイル検査演算子で判定出来ないと、少し面倒ですね。 ひとつの考え方としては、STDINから少しデータを読み出してみると言うのはあると思います。どちらにせよ、STDINがあるのならば読み込んで使うのでしょうから、先に読み込んでみて入っていれば…という処理です。 my $buffer = <STDIN>; if($buffer){ print 'STDIN'; } else{ print 'NOT STDIN'; } exit; STDINから$bufferにどれくらい読み込むかは、処理に応じて。最終的に使うのであれば全部でも良いし、単にテストするだけと言う使い方で冒頭の決められたバイト数とかでも良いと思います。ファイルポインタが先頭からずれますが、これも必要に応じてseekで戻してやります。 直接STDINの挙動に関する回答ではないですが、ファイル検査演算子を回避しても、上記のようにひとまず何とかする方法はあると思います。
補足
ありがとうございます ですが... my $buffer = <STDIN>; if($buffer){ print 'STDIN'; } else{ print 'NOT STDIN'; } exit; ですと、パイプからの標準入力がない場合には 最初の行で標準入力からの入力待ちになってしまい うまくいきません。 なんか、悩ましいです。
- hikomin
- ベストアンサー率63% (40/63)
参考まで。 v5.8.0 built for i686-linux v5.8.1-RC3 built for darwin-thread-multi-2level で0でした。 何が違うのでしょうねぇ…ただ、確かにこの辺のバージョンは、PerlIO関連の挙動変更があった筈なので、何か実装の違いがあるのかも知れません。 ところで、これは何がしたいのでしょうか。もしもサイズが取得したいとかであれば、length等を使うと良いです。 print length <STDIN>; 気をつけて使えば、この周辺の問題は回避出来るように思います。
補足
ありがとうございます。 補足しますと $ cat file | ./hogehoge.pl の場合と $ ./hogehoge.pl の場合で動作を分岐したいのです 例えば if( ( -s STDIN ) > 0 ){ print "STDIN\n"; }else{ print "Not STDIN\n"; } という感じにならないのです ^^;
お礼
ありがとうございました。 この方法でうまくいきそうです。