我正在尝试将STDOUT
和STDERR
重定向到日志文件中,但我还想将这些流打印到控制台。我使用的是Perl,我的代码如下:
use Capture::Tiny ':all';
my $stderr, $stdout;
($stdout, $stderr) = capture {
system($command);
};
print $stdout;
print $stderr;
可行,但如果命令等待用户输入,则程序不会将$stdout
打印到STDOUT
,直到按下某个键。有没有办法在需要用户输入之前将$stdout
打印到STDOUT
?逐行方法会很好。
提前谢谢!
答案 0 :(得分:0)
好吧,我对Capture::Tiny
并不熟悉所以这可能并不完全相关 - 一般来说,如果我想处理STDIN
,STDOUT
和/或{{ 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
类似,不同之处在于捕获输出并将其传递给原始STDOUT
和STDERR
。
只需更换函数调用,输出就会在变量和屏幕上结束。
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