首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Filehandle STDOUT作为仅用于输入的文件重新打开

Filehandle STDOUT作为仅用于输入的文件重新打开
EN

Stack Overflow用户
提问于 2017-03-16 21:25:25
回答 1查看 1.3K关注 0票数 3

给出了以下(中古时代)代码:

代码语言:javascript
复制
# Method to save and close the Standard output(STDOUT) and after to redirect the
# STDOUT in the log file of the step
sub doSomething{
    open(_OLDOUT, ">&STDOUT") or Error('001', "open", "Standard OUT", __PACKAGE__, $ERRNO);
    close(STDOUT) or Error('001', "close", "Standard OUT", __PACKAGE__, $ERRNO);
    open(STDOUT, ">".$self->{logFile}) or Error('001', "open", "Standard OUT", __PACKAGE__, $ERRNO);
}

我在第一个open命令中得到一个错误。这个错误是用函数Error格式化的,它给出了这样的消息:

代码语言:javascript
复制
ERROR-001: System command <open> failed in file Standard OUT for module core::AnotherModule. Reason: !

在出现此错误之前,我会收到一条警告:

代码语言:javascript
复制
Filehandle STDOUT reopened as FILE only for input at d:\Path/FirstModule.pm

下面是生成它的代码行(来自FirstModule.pm):

代码语言:javascript
复制
open FILE, "<".$file or Error('005',$file,__PACKAGE__,$ERRNO);

当然,这只是它背后的一大块代码。我在互联网上搜索,乍一看,STDOUT似乎关闭得更早,当我创建一个文件的句柄时,它被认为是STDOUT。我有什么选择?手动打开STDOUT以避免错误是否安全?另外,整个程序也是多线程的。

EN

回答 1

Stack Overflow用户

发布于 2017-03-16 22:23:15

在Perl程序启动时,文件描述符0为STDIN,并打开以供输入。并且打开文件描述符1和2 (STDOUTSTDERR)以进行输出。关闭这些标准文件句柄是完全合法的(偶尔也有一些很好的理由这样做)。

当您打开一个新的文件句柄时,Perl可能会使用新的文件描述符,或者它可能会重用以前关闭的旧文件描述符。如果您关闭了一个标准文件句柄,那么有很多理由可以解释为什么这样做,Perl可能会为新的文件句柄重用标准文件描述符。

Perl在打开文件句柄并分配标准文件描述符时执行的一项检查是,使用该文件描述符的预期模式检查文件句柄的模式,并在模式不匹配时发出警告。这是为了防止您对标准文件句柄做一些愚蠢的事情,因为这些文件句柄可能很难进行后续调试。

代码语言:javascript
复制
$ perl -Mdiagnostics -we 'close STDIN;open STDIN,">foo"'
Filehandle STDIN reopened as FOO only for output at -e line 1 (#2)
    (W io) You opened for writing a filehandle that got the same filehandle id
    as STDIN.  This occurred because you closed STDIN previously.

,但也会在您合法、正确地做其他事情时发出警告。

代码语言:javascript
复制
$ perl -Mdiagnostics -we '
my $input = <STDIN>;
close STDIN;
open my $fh, ">foo";
print $fh "your input was $input";
close $fh'
Filehandle STDIN reopened as $fh only for output at -e line 4 (#1)
    (W io) You opened for writing a filehandle that got the same filehandle id
    as STDIN.  This occurred because you closed STDIN previously.

这只是一个警告。

要抑制它,您可以在关闭标准文件句柄时将它们重定向到/dev/null (或在Windows上重定向到nul)。也就是说,它不是

代码语言:javascript
复制
close STDIN;
...
open FOO, '>foo';         # might get reassigned to fd 0

代码语言:javascript
复制
close STDIN;
open STDIN, '<nul';       # /dev/null on POSIX systems
...
open FOO, '>foo';         # won't get reassigned to fd 0
...
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42835415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档