题
我正在尝试使用SELECT更改系统功能的Stdout。但这似乎不起作用。系统输出将显示在控制台上,而不是重定向到文件。
use strict;
use warnings;
chdir "C:\\Documents and Settings\\" or die "cannot open the dir\n";
open FH, ">out.txt" or die "cannot open out.txt\n";
select FH or die " cannot change the stdout\n";
system "dir /a" ;
虽然我可以做 system "dir /a > out.txt"
, ,我想知道为什么上述代码不起作用。
解决方案
这 select
函数更改输出的默认文件Handle。它不会更改stdout,这指向任何指向输出的默认文件手机的指示。如果您想更改Stdout,则必须执行Ylebre或Jon的答案之类的事情。
当您启动子进程时,它将获得与父母相同的标准输出。不过,它不在乎父母的默认文件。
其他提示
您的代码问题是 system
命令不会为您捕获输出。您可以使用 qx//
:
use strict;
use warnings;
open my $fh, ">", "output.txt" or die $!;
my $oldfh= select $fh;
print qx/ls -a/;
select $oldfh;
close $fh or warn $!;
还有其他选项可以运行外部应用程序并获取读取其输出,例如 IPC::Open2
和 IPC::Open3
模块。默认情况下它们包括在Perl中。
旁注:不要将球用于档案处理:它们是全球,而全球是邪恶的。改用词汇变量(FH
VS. $fh
)。另外,您应该使用三个参数 open
而不是两个参数,因为前者比后者更安全。
也许 这个 帮助
在这种情况下,我不确定“选择”是您要寻找的内容。要将stdout重定向到文件,您可以执行以下操作:
use strict;
use warnings;
use IO::Handle;
open FH, "> out.txt";
STDOUT->fdopen( \*FH, 'w' ) or die $!;
print "Hello world!\n";
system "dir /a";
希望这可以帮助!
我在系统级别上重新分配文件描述符:
sub reopen($$$) {
open $_[0], $_[1]. '&='. fileno($_[2]) or die "failed to reopen: $!";
}
reopen *STDOUT, '>', $new_stdout_handle;
现在,您分支的任何内容都会认为$ new_stdout_handle是标准输出。
我粘贴了一个完整的榜样,要点: http://gist.github.com/129407
不隶属于 StackOverflow