我正在尝试使用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::Open2IPC::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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top