2009-11-24 49 views
2

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

我可以关闭perl中的STDERR使用;

close(STDERR) 

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

我试图

open(STDERR,">&STDERR"); 

,并没有工作。

在此先感谢。

+0

没办法,你不能这样做。 这是标准的unix安全生效。 – 2009-11-24 02:54:50

+0

@ J-16 SDiZ:“安全”?怎么会这样? – ysth 2009-11-24 05:25:04

+0

你在做什么?关闭并重新打开STDERR可能有更好的方法来做到这一点? – 2009-11-24 11:04:14

回答

11

为什么要关闭STDERR?

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

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

File :: Spec-> devnull()将返回相应的文件名 – ysth 2009-11-24 03:40:48

8

DUP它,然后再DUP DUP以重新打开它(检测代码错误作为一个练习的读者,尽管当STDERR不可能处理错误在挫败中锻炼):

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

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

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)“恢复”为真实的错误输出。

关闭其中一个dup'd文件描述符应该允许您继续使用另一个,尽管我期望在使用套接字时发生奇怪的事情。 (小心,挖掘手册并在需要时编写测试用例)。

哦,顺便说一句,并为open perlfunc里只显示你perl的方式做这些DUP的,但我必须承认,我不太充分理解语法的细微之处:

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

用于建议ysth 'dup's,但我认为它可以使用更多的背景和解释。 – PypeBros 2012-02-06 20:58:30