如何从子进程中读取错误?

时间:2017-04-09 01:45:47

标签: perl

我有一个Perl脚本来调用另一个程序。一节如下:

open(AMPL,"|ampl");
select(AMPL);
printf "option solver cplex;\n";
printf "var x1;\n"
printf "var x2;\n"
printf "minimize z: 3*x1 + 2*x2;\n";
printf "another_command;\n";
printf "data $ARGV[0];\n";
# More printfs
close(AMPL);

如果传递给ampl(即AMPL)的指令不正确,则此代码将无提示失败。可以将故障打印到STDERR或以其他方式捕获以中止脚本吗?

编辑:为了澄清,此代码将与AMPL解释器进行交互式会话:

$ ampl
ampl: option solver cplex;
>>> var x1;
>>> var x2;
>>> minimize z: 3*x1 + 2*x2;
>>> another_command;
>>> data foo;

1 个答案:

答案 0 :(得分:3)

使用模块(例如IPC::Run3)来获取调用程序打印到流的所有内容。

use warnings;
use strict;

use IPC::Run3;

my @cmd = ('xargs', '0', 'cat');  # display a file which name is piped in
#my @cmd = ('wc', 'c');            # count characters in the passed string

my $cmd_stdin = shift || $0;      # file name, from cmdline or this script

run3 \@cmd, [$cmd_stdin], \my $out, \my $err;

print $out if $out;  # Whatever was written by command to STDOUT
print $err if $err;  # ... and to STDERR

如果被调用的程序没有写入标准流,那么这就是调用者的手。

为了检查命令本身是否有效,请参阅this post

随着问题更新,将字符串提供给STDIN

AMPL
my @cmd = ('ampl');

my @stdin = ("arg_1\n", "arg_2\n", ..., "data $ARGV[0];\n");

run3 \@cmd, \@stdin, undef, \my $stderr;

语法要求输入为arrayref。通过设置上面的STDOUT,该计划的输出将转到undef,因为如果将其收集到$out变量中,则无法实时查看。< / p>