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

如何在Perl中打开()和关闭()STDERR?,perl,stderr,Perl,Stderr,您好 我可以使用perl关闭STDERR close(STDERR) 在执行了一些逻辑之后,我想再次打开它。 我怎么做 我试过了 open(STDERR,">&STDERR"); 但没有起作用 提前感谢。为什么要关闭STDERR 你可以把它放在一边 open(FOO, ">/dev/null"); # or ">nul" on Windows *TEMP = *STDERR; *STDERR = *FOO; ... then *STDERR = *TEMP; 首先

您好

我可以使用perl关闭STDERR

close(STDERR)
在执行了一些逻辑之后,我想再次打开它。 我怎么做

我试过了

open(STDERR,">&STDERR");
但没有起作用


提前感谢。

为什么要关闭STDERR

你可以把它放在一边

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

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


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

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

我猜您可能想做的是防止某些库在设计时在STDERR上生成输出。要做到这一点,您需要保持文件打开,但要在文件句柄列表中移动它。系统调用
new\u file\u descriptor=dup(old\u file\u descriptor)
在C中这样做,然后
dup2(some\u fd,2)
将某个文件“激活”为stderr,并
dup2(new\u stderr\u descriptor,2)
恢复到实际的错误输出

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

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

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

不行,你不能这么做。这是现行的标准unix安全性。@J-16 SDiZ:“安全性”?怎么会这样?你在干什么?可能有比关闭并重新打开STDERR更好的方法?Capture::Tiny可能有用。这允许您有条件地捕获STDOUT/STDERR,并可以选择在以后处理它File::Spec->devnull()将返回适当的文件名credit to ysth,以建议
dup
s,但我认为它可以使用更多的背景和解释。
open my $oldout, ">&STDOUT"     or die "Can't dup STDOUT: $!";
open OLDERR,     ">&", \*STDERR or die "Can't dup STDERR: $!";
# ...