如何重定向和恢复STDOUT

STDOUT是Perl的标准输出文件句柄。除非指定了文件句柄,否则Perl中的所有标准打印输出都将发送到终端。由于STDOUT只是一个全局变量,因此它可以被重定向和恢复。想在程序中实现日志记录而不必更改源代码中的每个print语句吗?想捕获Perl CRON作业的标准输出吗?请继续阅读。

终端重定向

在您启动最喜欢的文本编辑器并开始修改Perl代码之前,您可能只需要在终端中重定向程序输出。在基于UNIX的系统上,您可以使用“>”写入文件,使用“>>”追加到文件。写入和追加都将创建文件,如果文件不存在的话。

perl program.pl > /path/to/log.txt
perl program.pl >> /path/to/log.txt

在Windows上,可以使用PowerShell通过管道运算符(“|”)和“set-content”来写入,或使用“add-content”来追加(管道不会重定向STDERR)。

perl program.pl | set-content /path/to/log.txt
perl program.pl | add-content /path/to/log.txt

Perl解决方案

如果终端重定向不足以满足您的需求,您可以使用以下Perl解决方案之一。以下所有解决方案都使用autodie,它消除了在每个打开语句后附加经典“|| or die $!”语法的需要。

使用select重定向STDOUT

Perl的内置函数select可以将标准输出文件句柄更改为提供的文件句柄。这使得全局重定向和恢复标准输出变得容易。

use feature qw/say/;
use autodie;

# open filehandle log.txt
open (my $LOG, '>>', 'log.txt');

# select new filehandle
select $LOG;

say 'This should be logged.';

# restore STDOUT
select STDOUT;

say 'This should show in the terminal';

使用local重定向STDOUT

Perl的内置函数local是重定向STDOUT的另一种选择。local函数为传入的任何变量创建一个词法作用域的副本。通过在do块中包围local,下面的代码将STDOUT的重定向限制在块作用域内,并在关闭块括号(“}”)后自动恢复STDOUT。根据定义,这不是重定向STDOUT的全局解决方案。

use feature qw/say/;
use autodie;

do {
    local *STDOUT;

    # redirect STDOUT to log.txt
    open (STDOUT, '>>', 'log.txt');

    say 'This should be logged.';
};
say 'This should show in the terminal';

使用文件句柄重定向STDOUT

重定向和恢复STDOUT的第三种方法是复制在替换它之前的标准输出文件句柄。然后可以在需要时恢复此副本。与select一样,这将对Perl程序产生全局影响。

use feature qw/say/;
use autodie;

# copy STDOUT to another filehandle
open (my $STDOLD, '>&', STDOUT);

# redirect STDOUT to log.txt
open (STDOUT, '>>', 'log.txt');

say 'This should be logged.';

# restore STDOUT
open (STDOUT, '>&', $STDOLD);

say 'This should show in the terminal';


本文最初发布于PerlTricks.com

标签

David Farrell

David是一位专业程序员,他经常推文博客关于代码和编程艺术。

浏览他们的文章

反馈

这篇文章有什么问题吗?请通过在GitHub上打开问题或拉取请求来帮助我们。