在进程等待用户输入时将 STDOUT 重定向到文件
Redirect STDOUT to a file while process is waiting for user input
我正在尝试将 STDOUT
和 STDERR
重定向到日志文件中,但我还想将这些流打印到控制台。我正在使用 Perl,我的代码如下所示:
use Capture::Tiny ':all';
my $stderr, $stdout;
($stdout, $stderr) = capture {
system($command);
};
print $stdout;
print $stderr;
它可以工作,但如果命令等待用户输入,则程序不会打印 $stdout
到 STDOUT
,直到按下某个键。有没有办法在需要用户输入之前将 $stdout
打印到 STDOUT
?逐行处理就好了。
提前致谢!
嗯,我对 Capture::Tiny
不熟悉,所以这可能不完全相关 - 但一般来说,如果我想处理 STDIN
、STDOUT
and/or STDERR
然后我看向 open
(如果它只是一个),或 IPC::Open2
和 [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
然后(理想情况下)waitpid
以在您完成后清理流程。
您需要使用 Capture::Tiny's tee
而不是 capture
。
The tee
function works just like capture
, except that output is captured as well as passed on to the original STDOUT
and STDERR
.
只需替换函数调用,您的输出将同时出现在变量和屏幕上。
use Capture::Tiny ':all';
my $stderr, $stdout;
($stdout, $stderr) = tee {
system($command);
};
我能想到的简单方法:
#! /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
我正在尝试将 STDOUT
和 STDERR
重定向到日志文件中,但我还想将这些流打印到控制台。我正在使用 Perl,我的代码如下所示:
use Capture::Tiny ':all';
my $stderr, $stdout;
($stdout, $stderr) = capture {
system($command);
};
print $stdout;
print $stderr;
它可以工作,但如果命令等待用户输入,则程序不会打印 $stdout
到 STDOUT
,直到按下某个键。有没有办法在需要用户输入之前将 $stdout
打印到 STDOUT
?逐行处理就好了。
提前致谢!
嗯,我对 Capture::Tiny
不熟悉,所以这可能不完全相关 - 但一般来说,如果我想处理 STDIN
、STDOUT
and/or STDERR
然后我看向 open
(如果它只是一个),或 IPC::Open2
和 [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
然后(理想情况下)waitpid
以在您完成后清理流程。
您需要使用 Capture::Tiny's tee
而不是 capture
。
The
tee
function works just likecapture
, except that output is captured as well as passed on to the originalSTDOUT
andSTDERR
.
只需替换函数调用,您的输出将同时出现在变量和屏幕上。
use Capture::Tiny ':all';
my $stderr, $stdout;
($stdout, $stderr) = tee {
system($command);
};
我能想到的简单方法:
#! /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