Perl,open2,stdin不运行

时间:2016-12-12 10:56:14

标签: perl gnuplot stdin

我试图运行" gnuplot"使用open2处理并向其发送命令,但没有任何反应。我是perl的新手,所以我对事情的运作方式有点困惑,关于这个模块的官方文档对我来说并不清楚。

use IPC::Open2;
use strict;
use warnings;

my($w, $r);

my $pid = open2($w, $r, "gnuplot") or die "$!";
# print "pid was $pid\n";
print $w "reset\n";
print $w "dx=5.\n";
print $w "n=2\n";
print $w "total_box_width_relative=0.75\n";
print $w "gap_width_relative=0.1\n";
print $w "d_width=(gap_width_relative+total_box_width_relative)*dx/2.\n";
print $w "reset\n";
print $w "set term png truecolor font 'arial,10' fontscale 1.0 size 800, 400\n";
print $w "set output 'test.png'\n";
print $w "set xlabel 'time' offset '0', '-2'\n";
print $w "set ylabel 'load'\n";
print $w "set autoscale xfixmin\n";
print $w "set autoscale xfixmax\n";
print $w "set autoscale y\n";
print $w "set datafile separator '\\t'\n";
print $w "set xdata time\n";
print $w "set timefmt '%d-%m-%Y'\n";
print $w "set xrange ['08-12-2016':'23-02-2025']\n";
print $w "set format x '%m/%d/%Y'\n";
print $w "set xtic rotate by 30 offset character -4,-2\n";
print $w "set xtics font ', 8'\n";
print $w "set grid\n";
print $w "set boxwidth total_box_width_relative/n relative\n";
print $w "set style fill transparent solid 0.5 noborder\n";
print $w "plot 'test.dat' u 1:2 w boxes lc rgb'blue' notitle,\\\n";
print $w "   'test.dat' u 1:3 w boxes lc rgb'red' notitle\n";
close($w);
waitpid($pid, 0);
if ($?) {
    print "That child exited with wait status of $?\n";
}

test.dat结构示例:

08-12-2016  3   6
09-12-2016  56  44

我做错了什么?

1 个答案:

答案 0 :(得分:2)

我很确定你在open2中错误地处理了文件句柄的排序:

 $pid = open2($chld_out, $chld_in, 'some', 'cmd', 'and', 'args');

E.g。您的示例中的$wSTDOUT进程,因此您打印到它不会做任何事情。而且因为你正在做waitpid - 然后关闭'输出'文件句柄 - 你将无限期地等待,因为进程仍在从它的输入文件句柄中读取。

我还强烈建议单字母变量名称无论如何都是个坏主意。您也可以在my语句中嵌入open2,所以:

my $pid = open2 ( my $child_out, my $child_in, "gnuplot" ); 

作为一些小的风格点 - 我建议一遍又一遍地复制print $w并不是理想的做法。

怎么样:

#!/usr/bin/env perl
use strict;
use warnings;

use IPC::Open2;
use IO::Select;

my $pid = open2( my $gnuplot_out, my $gnuplot_in, "gnuplot" );
my $select = IO::Select->new($gnuplot_out);

while ( my $command = <DATA> ) {
   print {$gnuplot_in} $command;
   while ( $select->can_read(0) ) {
      print "Response from gnuplot: ", scalar <$gnuplot_out>, "\n";
   }
}

close($gnuplot_in);
while ( $select->can_read(0) ) {
   print "Response from gnuplot: ", scalar <$gnuplot_out>, "\n";
}

close($gnuplot_out);
waitpid( $pid, 0 );
if ($?) {
   print "That child exited with wait status of $?\n";
}

__DATA__
reset
dx=5.
n=2
total_box_width_relative=0.75
gap_width_relative=0.1
d_width=(gap_width_relative+total_box_width_relative)*dx/2.
reset
set term png truecolor font 'arial,10' fontscale 1.0 size 800, 400
set output 'test.png'
set xlabel 'time' offset '0', '-2'
set ylabel 'load'
set autoscale xfixmin
set autoscale xfixmax
set autoscale y
set datafile separator '\\t'
set xdata time
set timefmt '%d-%m-%Y'
set xrange ['08-12-2016':'23-02-2025']
set format x '%m/%d/%Y'
set xtic rotate by 30 offset character -4,-2
set xtics font ', 8'
set grid
set boxwidth total_box_width_relative/n relative
set style fill transparent solid 0.5 noborder
plot 'test.dat' u 1:2 w boxes lc rgb'blue' notitle,\\
   'test.dat' u 1:3 w boxes lc rgb'red' notitle