当进程正在等待用户输入时,将STDOUT重定向到文件

时间:2015-09-28 11:22:47

标签: perl stdin

我正在尝试将STDOUTSTDERR重定向到日志文件中,但我还想将这些流打印到控制台。我使用的是Perl,我的代码如下:

use Capture::Tiny ':all';

my $stderr, $stdout;

($stdout, $stderr) = capture {
    system($command);
};

print $stdout;
print $stderr;

可行,但如果命令等待用户输入,则程序不会将$stdout打印到STDOUT,直到按下某个键。有没有办法在需要用户输入之前将$stdout打印到STDOUT?逐行方法会很好。

提前谢谢!

3 个答案:

答案 0 :(得分:0)

好吧,我对Capture::Tiny并不熟悉所以这可能并不完全相关 - 一般来说,如果我想处理STDINSTDOUT和/或{{ 1}}然后我会查看STDERR(如果它只是一个),或IPC::Open2和[open打开多个附加到流程的文件描述符。

IPC::Open3][1]

虽然我建议而不是示例 - 你可以使用词法文件句柄:

use IPC::Open3;
$pid = open3(\*CHLD_IN, \*CHLD_OUT, \*CHLD_ERR,
                'some cmd and args', 'optarg', ...);

use IPC::Open2;
$pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');

然后您可以从文件句柄中读取和写入(请记住 - 默认情况下,读取将被阻止)。

您确实需要my($chld_out, $chld_in); $pid = open2($chld_out, $chld_in, 'some cmd and args'); 然后(理想情况下)close来清理流程。

答案 1 :(得分:0)

您需要使用Capture::Tiny's tee代替capture

  

tee功能的工作原理与capture类似,不同之处在于捕获输出并将其传递给原始STDOUTSTDERR

只需更换函数调用,输出就会在变量和屏幕上结束。

use Capture::Tiny ':all';

my $stderr, $stdout;

($stdout, $stderr) = tee {
    system($command);
};

答案 2 :(得分:-1)

我能想到的简单方法:

#! /usr/bin/perl -w

# Using perl one liner as a command here
# which prints a string to STDOUT and STDERR
my $cmd = "perl -e 'print STDOUT \"stdout\n\"; print STDERR \"stderr\n\";'";

my $log = "./test.log";

# using "2>&1" we are redirecting stderr also to stdout
system("$cmd 2>&1 | tee $log");

# Sample run results in both the strings getting printed to console as well as to log file
> perl test.pl
stderr 
stdout

> cat test.log 
stderr
stdout