如何在Perl中打开()和关闭()STDERR?

时间:2009-11-24 02:46:08

标签: perl stderr

问候,

我可以使用;

关闭perl中的STDERR
close(STDERR)

在执行一些逻辑之后,我想再次打开它。 我该怎么办?

我试过

open(STDERR,">&STDERR");

并没有奏效。

提前致谢。

3 个答案:

答案 0 :(得分:11)

你为什么要关闭STDERR?

你可以把它放在一边......

open(FOO, ">/dev/null"); # or ">nul" on Windows
*TEMP = *STDERR;
*STDERR = *FOO;
... then
*STDERR = *TEMP;

答案 1 :(得分:8)

首先复制它,然后复制它以重新打开它(错误检查留给读者练习,虽然在STDERR不可用时处理错误可能是一种挫败的练习):

open(my $saveerr, ">&STDERR");
close(STDERR);
open(STDERR, ">&", $saveerr);

请注意,当您关闭STDERR时,您将释放文件描述符2;如果您打开另一个文件并且它获得了文件描述符2,那么您使用的任何非Perl库都可能认为其他文件是stderr。

答案 2 :(得分:1)

STDERR由父进程提供。它不一定是一些常规文件,所以除非你不打算再写它,否则你最好保持开放状态。我避免玩弄tty shell命令,并在这里重新打开/ dev / pts / XX,真诚地说:这只会让你陷入困境

我想您可能想要做的是阻止某些库在STDERR上生成输出,同时设计这样做。要做到这一点,您需要保持文件打开,但在文件句柄列表中移动它。系统调用new_file_descriptor = dup(old_file_descriptor)在C中执行此操作,之后dup2(some_fd,2)到"激活"一些文件为stderr,dup2(new_stderr_descriptor,2)为" resume"到真正的错误输出。

关闭其中一个dup文件描述符应该允许你继续使用另一个文件描述符,尽管我在这里使用套接字时会发现奇怪的事情。 (注意,如果需要,可以挖掘手册并编写测试用例)。

哦,顺便说一句,open的perlfunc联机帮助页只是向您展示了执行这些重复操作的perl方法,尽管我必须承认我并不完全理解该语法的细微之处:

open my $oldout, ">&STDOUT"     or die "Can't dup STDOUT: $!";
open OLDERR,     ">&", \*STDERR or die "Can't dup STDERR: $!";
# ...