プロが教えるわが家の防犯対策術!

cmd1.exe は、標準入力でデータを読み込み、
結果を標準出力するようなプログラムです。

$ cmd1.exe < test.txt
d090206
p314159
r214142
$

このcmd1.exeをperlスクリプト内で呼び出し、その結果を求めるやり方として、
従来、次のようなやりかた・・・

open(OUT,">temp.txt") || die "$!";
foreach(・・・){
中略
print OUT "$_\n";
}
close(OUT);

my @answer = `cmd1.exe < temp.txt`;

foreach(@answer){
:

}

unlink("temp.txt");

のようなことをしています。
今は、中間ファイルを書き出しては、最後にファイル削除して、ということをやっているのですが、

このような中間ファイルを使わずに、パイプ(?)という仕組みを使って、同じように処理させるには、
どのようにコーディングすれば良いですか?

試してみたこととして、
open(PIPE,"|cmd1.exe");
foreach(・・・){
中略
print PIPE "$_\n";
}
close(PIPE);
のようにすれば、exeの呼び出しそのものは出来たのですが、
その標準出力の結果を上手く内部で受け取れません。

よろしくお願い致します。

A 回答 (3件)

#2です。

あなたがなさりたいことは、こういうことですか。
#! /bin/perl
use IPC::Open2;
$pid = open2 RFH,WFH,"cmd1.exe";

# 子プロセスへ出力
foreach (1..10){
print WFH "AAAA",$_,"\n";
}
close WFH;
# 子プロセスから入力
@list = <RFH>;
foreach(@list){
print "XXX",$_;
}
--------------------------------
cmd1.exeのソースの内容は
#! /bin/perl
while(<>){
print $.,":",$_;
}
-----------------------
以下、実行結果
XXX1:AAAA1
XXX2:AAAA2
XXX3:AAAA3
XXX4:AAAA4
XXX5:AAAA5
XXX6:AAAA6
XXX7:AAAA7
XXX8:AAAA8
XXX9:AAAA9
XXX10:AAAA10
-----------
cmd1.exeは標準入力からデータを受け取り、標準出力へ処理結果を出力する。
perl本体は、cmd1.exeにとっての入力データを出力用パイプへ出力し、
cmd1.exeの処理結果を入力用パイプから読みとる。

この回答への補足

お返事が遅くなり申し訳ございません。
open2()についてネットで調べて、出来たつもりになっていたのですが、
その後、上手く行かずにてこずっています。
上記、示していただいたサンプルでは、
close WFH;
の後、処理が止まってしまい、その後、何かキー入力して、ctrl+cを押すと、
-------------------------------------------------------------
Terminating on signal SIGINT(2)

D:\FACTORY\Perl\OPEN2>
D:\FACTORY\Perl\OPEN2>aa
'aa' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

D:\FACTORY\Perl\OPEN2>
-------------------------------------------------------------
のようになってしまいます。
ここで、aa は、close WFH語に停止しているときに、キー入力した文字です。
---
※申し遅れました。環境は、Windows-XP/ActivePerlのv5.8.6を使っています。

補足日時:2009/02/11 10:01
    • good
    • 0
この回答へのお礼

お世話になります。
サンプルプログラムのご提示やその動作結果まで教えて頂き、ありがとうございました。

その後、調べましたら、WindowsのActivePerlでは、
open2( )は機能しないようなことが書いてありました。

また、上記で止まってしまっているのは、close部分ではなくて、
@list = <RFH>;
の部分のようです。

もともと、やりたかったことは、tatsu99様でご推察して下さったように、
ある外部コマンドへの標準入力、および、そのコマンドからの標準出力を、
テンポラリなファイルを作らずにスクリプト本体でやりとりすること。
でした。
WindowsのActivePerlで実現する方法が他にありましたら、
お手数ですが、よろしくお願い致します。

お礼日時:2009/02/11 13:30

なにをなさりたいのかがよくわかりませんが、


cmd1.exe は標準入力からデータを読み込み、結果を標準出力へ出力する。
cmd2.exeはcmd1.exeの出力結果を入力データとして受け取りたいと言うことでしょうか。
もし、そうなら
cmd1.exe < test.txt | cmd2.exe 
で良いとおもいます。
cmd2.exeは、標準入力からデータを受け取るようにコーディングして下さい。
(環境(OS等)が不明なのでlinuxという前提で回答しました)
    • good
    • 0

・普通は open2 かな


・pipe とか fork でがんばることも可能
・名前つきパイプを作るのは可能だけど若干あやしい
    • good
    • 0
この回答へのお礼

お礼が遅くなり、申し訳ございませんでした。
open2でgoogle検索し、目的のことが出来ることが分かりました。
すばやいご回答、ありがとうございました。

お礼日時:2009/02/10 22:57

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!