• ベストアンサー

中間ファイルを使わずに処理させる方法

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の呼び出しそのものは出来たのですが、 その標準出力の結果を上手く内部で受け取れません。 よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.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の処理結果を入力用パイプから読みとる。

goku3
質問者

お礼

お世話になります。 サンプルプログラムのご提示やその動作結果まで教えて頂き、ありがとうございました。 その後、調べましたら、WindowsのActivePerlでは、 open2( )は機能しないようなことが書いてありました。 また、上記で止まってしまっているのは、close部分ではなくて、 @list = <RFH>; の部分のようです。 もともと、やりたかったことは、tatsu99様でご推察して下さったように、 ある外部コマンドへの標準入力、および、そのコマンドからの標準出力を、 テンポラリなファイルを作らずにスクリプト本体でやりとりすること。 でした。 WindowsのActivePerlで実現する方法が他にありましたら、 お手数ですが、よろしくお願い致します。

goku3
質問者

補足

お返事が遅くなり申し訳ございません。 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を使っています。

その他の回答 (2)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

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

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

・普通は open2 かな ・pipe とか fork でがんばることも可能 ・名前つきパイプを作るのは可能だけど若干あやしい

goku3
質問者

お礼

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

関連するQ&A