如何在变量中捕获Perl的STDOUT?

时间:2022-01-18 00:05:33

I am calling a function that writes to STDOUT using print. How can I capture this in a variable?

我正在调用一个使用print写入STDOUT的函数。如何在变量中捕获它?

Note that all this happens within the same process.

请注意,所有这些都发生在同一个过程中。

2 个解决方案

#1


17  

The new, cool way to handle this is with Capture::Tiny. You can use it surgically to affect just the part of the program where you need it without disturbing anything else. But, I'd probably do what cjm recommends since that doesn't require a module.

处理这个问题的新方式很酷,就是使用Capture :: Tiny。您可以通过手术使用它来影响您需要它的程序部分,而不会打扰其他任何事情。但是,我可能会做cjm推荐的,因为它不需要模块。

#2


11  

If the code in question is not using STDOUT explicitly (i.e., it just does print "..."), you can use select to change the filehandle that print uses:

如果有问题的代码没有明确使用STDOUT(即,它只是打印“...”),您可以使用select来更改打印使用的文件句柄:

my $output;
open(my $outputFH, '>', \$output) or die; # This shouldn't fail
my $oldFH = select $outputFH;
call_code_that_prints();
select $oldFH;
close $outputFH;

print $output;    # Here's what we collected

Using select makes it easier to restore STDOUT afterward. Closing and reopening STDOUT is harder to undo. Note that select does not affect STDOUT itself, so it doesn't affect external processes, but you said you didn't have any. It also doesn't affect code that does something like print STDOUT "...".

使用select可以更容易地恢复STDOUT。关闭并重新打开STDOUT很难撤消。请注意,select不会影响STDOUT本身,所以它不会影响外部进程,但是你说你没有。它也不会影响执行print STDOUT“......”之类的代码。

If the select method isn't sufficient for your needs, I'd recommend you try Capture::Tiny. It can capture output from external programs and code that writes to STDOUT explicitly. But it can't (currently) capture only STDOUT; it always captures both STDOUT and STDERR (either separately or merged into one string).

如果select方法不足以满足您的需求,我建议您尝试Capture :: Tiny。它可以捕获外部程序的输出和明确写入STDOUT的代码。但它(目前)不能仅捕获STDOUT;它总是捕获STDOUT和STDERR(单独或合并为一个字符串)。

#1


17  

The new, cool way to handle this is with Capture::Tiny. You can use it surgically to affect just the part of the program where you need it without disturbing anything else. But, I'd probably do what cjm recommends since that doesn't require a module.

处理这个问题的新方式很酷,就是使用Capture :: Tiny。您可以通过手术使用它来影响您需要它的程序部分,而不会打扰其他任何事情。但是,我可能会做cjm推荐的,因为它不需要模块。

#2


11  

If the code in question is not using STDOUT explicitly (i.e., it just does print "..."), you can use select to change the filehandle that print uses:

如果有问题的代码没有明确使用STDOUT(即,它只是打印“...”),您可以使用select来更改打印使用的文件句柄:

my $output;
open(my $outputFH, '>', \$output) or die; # This shouldn't fail
my $oldFH = select $outputFH;
call_code_that_prints();
select $oldFH;
close $outputFH;

print $output;    # Here's what we collected

Using select makes it easier to restore STDOUT afterward. Closing and reopening STDOUT is harder to undo. Note that select does not affect STDOUT itself, so it doesn't affect external processes, but you said you didn't have any. It also doesn't affect code that does something like print STDOUT "...".

使用select可以更容易地恢复STDOUT。关闭并重新打开STDOUT很难撤消。请注意,select不会影响STDOUT本身,所以它不会影响外部进程,但是你说你没有。它也不会影响执行print STDOUT“......”之类的代码。

If the select method isn't sufficient for your needs, I'd recommend you try Capture::Tiny. It can capture output from external programs and code that writes to STDOUT explicitly. But it can't (currently) capture only STDOUT; it always captures both STDOUT and STDERR (either separately or merged into one string).

如果select方法不足以满足您的需求,我建议您尝试Capture :: Tiny。它可以捕获外部程序的输出和明确写入STDOUT的代码。但它(目前)不能仅捕获STDOUT;它总是捕获STDOUT和STDERR(单独或合并为一个字符串)。