使用 gnuplot 返回动态图片(续)

前面说到这个简单的 CGI 技巧后,stevenshen 在 facebook 上提出了一些疑问。虽然给了一些解决的方案,但是觉得还是不很完美,今天早上突然受到启发,因为不 work 的原因有一部分是 echo 引起的,造成命令行参数过长(如果数据很多)。但是如果将数据放在一个临时文件又觉得不合算,放在临时文件里面的好处是,调用 cat 就行了,命令行的长度就不会受到影响。

因此,最好的方法是直接使用管道,将输入灌入管道,如果所在的操作系统支持 fork,那么 perl 可以很容易完成这个任务,perl 在打开文件的时候可以用 | 表示管道,如果我们需要将输入喂进一个程序,可以用 |-,如果是需要从某个程序读输出,则是 -|,这里 | 哪边留空哪边是给我们的程序控制的,那么 – 可以用某些程序直接替代,比如 gnuplot。

管道工作的方式就是修改某些 file descriptor,然后 fork,比如我们创建的 gnuplot,就希望它的输入不是 stdin,但是输出还是 stdout(和父进程一致),这样我们在父进程对其标准输入进行写就可以了。下面是一个例子

my $pid = open PIPE, "|-";
die "Cannot fork $!" unless defined $pid;

unless ( $pid ) {
    exec( $gnuplot ) or die "Cannot open pipe to gnuplot: $!";
}

后面在父进程里面对 PIPE 进行 print,把我们的程序输入,最后 close PIPE ; 即可。

这个方法额外的好处是比较安全,因为直接 echo 的时候,如果输入里面含有一些恶意的东西就比较麻烦,因为整个语句是在 shell 里面解析的,但是现在的做法输入完全喂给子进程,一般该进程不会处理偏系统的功能,比如 rm 什么的,因此整体上安全一些。

Advertisements
使用 gnuplot 返回动态图片(续)

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s