2

问候 ,

我可以使用 perl 关闭 STDERR;

close(STDERR)

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

我试过

open(STDERR,">&STDERR");

并没有工作。

提前致谢。

4

3 回答 3

11

为什么要关闭 STDERR?

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

open(FOO, ">/dev/null"); # or ">nul" on Windows
*TEMP = *STDERR;
*STDERR = *FOO;
... then
*STDERR = *TEMP;
于 2009-11-24T03:03:10.240 回答
9

首先 dup 它,然后 dup dup 以重新打开它(错误检查留给读者作为练习,尽管在 STDERR 不可用时处理错误可能是令人沮丧的练习):

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

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

于 2009-11-24T03:39:19.760 回答
1

STDERR 由父进程提供。它不一定是一些常规文件,所以你最好保持打开状态,除非你不打算再在上面写了。老实说,我会避免玩弄ttyshell 命令并在这里重新打开 /dev/pts/XX :那只会给你带来麻烦

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

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

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

open my $oldout, ">&STDOUT"     or die "Can't dup STDOUT: $!";
open OLDERR,     ">&", \*STDERR or die "Can't dup STDERR: $!";
# ...
于 2012-02-06T20:57:18.490 回答