mak*_*mak 1 perl warnings stdout filehandle
执行以下简化代码时:
use strict; # [01]
use warnings FATAL => 'unopened'; # [02]
# [03]
my ($inHandle, $outHandle) = (\*STDIN, \*STDOUT); # [04]
print $outHandle "STDOUT 1\n"; # [05]
# [06]
# $outHandle re-assigned to outputA.txt ??? # [07]
open($outHandle, ">outputA.txt") or die ("A: $!\n"); # [08]
print $outHandle "FILE A\n"; # [09]
print "STDOUT? 2\n"; # [10]
print STDOUT "STDOUT 3\n"; # [11]
close $outHandle; # [12]
# [13]
# $outHandle is closed # [14]
print STDOUT "STDOUT 4\n"; # [15]
print "STDOUT? 5\n"; # [16]
print $outHandle "FILE CLOSED\n"; # [17]
# [18]
# $outHandle re-assigned to outputA.txt ??? # [19]
open($outHandle, ">outputB.txt") or die ("B: $!\n"); # [20]
print $outHandle "FILE B\n"; # [21]
close $outHandle; # [22]
Run Code Online (Sandbox Code Playgroud)
我遇到以下奇怪的行为:
$outputHandle(第 [13] 行)时,即使use warnings FATAL => 'unopened';使用,也不会发出警告。| 标准输出 | 输出A.txt | 输出B.txt |
|---|---|---|
| 标准输出 1 | 文件A | 文件乙 |
| 标准输出?2 | ||
| 标准输出 3 |
这是我期望的输出,假设第 [17] 行被注释掉并且不会引发 warnings FATAL => 'unopened'
| 标准输出 | 输出A.txt | 输出B.txt |
|---|---|---|
| 标准输出 1 | 文件A | 文件乙 |
| 标准输出?2 | ||
| 标准输出 3 | ||
| 标准输出 4 | ||
| 标准输出?5 |
作为旁注:
当标准输出流†被重定向(重新打开)到一个文件时,就无法用它打印到控制台;本来要去那里的内容现在已连接到该文件。所以一旦完成,所有其他打印到STDOUT,以一种或另一种方式完成,结束在文件中。
然后那个文件句柄被关闭;之后就不能再打印STDOUT了。‡
所以第一个表是人们应该期待的。
打印到未打开的文件句柄时,我确实收到警告,因此对于STDOUT关闭后的任何和所有打印。 编辑...没有FATAL => 'unopened'但正常warnings启用,即(我如何测试此答案)。但是,仅使用该警告类别,就没有打印到已关闭文件句柄(已初始化然后关闭的文件句柄)的警告。请参阅此页面。
一些注意事项:
文档中的几页要学习:open , and Playing with STDIN and STDOUT (old perlopentut) , and open FILEHANDLE in perlfunc
有一些方法可以通过控制来操作标准流。一种是“ dup ”(复制)它,以便在它被重定向、使用和关闭后可以恢复它。想到的一些例子:在关于 STDOUT和关于重定向的帖子中。(请注意,这$fh = \*STDOUT会创建一个别名,因此当其中一个更改时,另一个也会更改。)
或者,在一个单独的范围内(块会做得很好),这样做local *STDOUT;之后所有提到的STDOUT都将与这个本地副本一起工作。一旦离开范围,全局范围就会恢复。
或者您可以使用select而不是弄乱STDOUT本身。
其中大部分都在perl.com 文章中得到了很好的总结。有关更多信息,请参阅此页面
“三个论点”open更好:(open my $fh, '<', $file ...并检查or die $!)
它被称为“句柄”,而不是“句柄”
† 该文件描述符1,为此,Perl提供一个打开STDOUT的文件句柄(真*STDOUT glob的,但是*当一个文件句柄,预计可以被省略,或作为一个适当的参考\*STDOUT)
‡即使STDOUT没有首先被重定向,一旦它关闭,就没有与标准输出流的连接,也没有像以前那样重新打开它的简单方法。(当然有办法把东西放在终端上。)
一般来说,关闭STDOUT不是一个好主意,因为很多人都希望它是开放的。一方面,一旦 fd1 被腾空,其他东西可能会被分配,带来奇怪的麻烦(参见这篇文章和Perl bug #23838)。如果您的程序分叉(以某种方式),并且子进程继承了他们不可能期望的东西怎么办?可能在下一行调用的库怎么办?等等。
有更好的方法来操作STDOUT,在文本中提到和链接。
如果您需要 STDOUT离开,至少将其重定向到/dev/null(nul在 Windows 上)而不是完全关闭它。
| 归档时间: |
|
| 查看次数: |
120 次 |
| 最近记录: |