如何将eval输出重定向到文件?

时间:2017-05-30 17:40:41

标签: perl eval

我正在编写一个Perl脚本,其中我读取包含Perl代码段和非Perl数据的文件。

处理完文件后,我将它们写入临时文件(生成的脚本),然后使用eval命令执行。我不想单独运行生成的脚本,因为我需要使用主脚本中的变量在生成的脚本中进行插值

我需要将eval命令的输出重定向到文件。有关如何实现这一目标的任何建议吗?

脚本中的步骤:

  1. READ_FILE

  2. 处理文件

  3. 使用临时文件名回写

  4. 读取临时文件(my $file_name = read_file('temp_file_name')

  5. eval(eval $file_name

  6. 感谢帮助。

3 个答案:

答案 0 :(得分:5)

您可以使用Capture::Tiny中的capture_stdout来获取eval的输出。

use strict;
use warnings;
use Capture::Tiny 'capture_stdout';

my $stdout = capture_stdout {
    eval q{print "Hello World!\n";};
};

open my $fh, '>', 'foo.txt' or die $!;
print $fh $stdout;

答案 1 :(得分:5)

这可以在没有任何额外模块的情况下完成

use strict;
use warnings;

open my $fh, '>', 'foo.txt' or die $!;
my $old_fh = select $fh;

eval q{ print "Hello World!\n"; };

select $old_fh;

答案 2 :(得分:0)

TLDR 答案

use Capture::Tiny; 带有 capture_merged()capture()。如果您喜欢它作为快捷方式,您可以使用 capture_stdout()

输出?哪个输出流? STDOUT 还是 STDERR?

根据Perl,输出可以是以下形式:

  • STDOUT — 通常由 print() 等语句引起。
  • STDERR — 通常由 warn() 等语句引起。

您可以使用 Capture::Tiny 来合并 STDOUTSTDERR

my ($merged,  @result) = capture_merged { eval $codetoeval };

或者,您可以使用 Capture:Tiny 将它们分开:

my ($stdout, $stderr, @result) = capture { eval $codetoeval };

如果您只需要这些形式的输出,您还可以选择 capture_stdout()capture_stderr()。如果您只有 print() 语句,那么 capture()capture_stdout() 将给出相同的结果。

完整演示

use Capture::Tiny ':all';
my $codetoeval = 'print "Hello, World!";';
my ($merged,  @result) = capture_merged { eval $codetoeval };
die "Merge Fail" if !@result;
print("Output : " . $merged);
open my $fh, '>', 'foo.txt' or die $!;
print $fh $stdout;

Full Working Online Demo at IDEOne

输出:Hello, World!