【问题标题】:Redirect STDOUT to a file while process is waiting for user input在进程等待用户输入时将 STDOUT 重定向到文件
【发布时间】:2015-09-28 20:34:18
【问题描述】:

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

use Capture::Tiny ':all';

my $stderr, $stdout;

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

print $stdout;
print $stderr;

它可以工作,但是如果命令等待用户输入,程序不会将$stdout 打印到STDOUT,直到按下一个键。有没有办法在需要用户输入之前将$stdout 打印到STDOUT?逐行方法就可以了。

提前感谢您!

【问题讨论】:

    标签: perl stdin


    【解决方案1】:

    好吧,我不熟悉 Capture::Tiny,所以这可能并不完全相关 - 通常,如果我想要处理 STDINSTDOUT 和/或 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 以在您完成后清理该过程。

    【讨论】:

    • 谢谢。我选择了 tee 解决方案,因为它需要的工作量少很多。
    【解决方案2】:

    您需要使用Capture::Tiny's tee 而不是capture

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

    只需替换函数调用,您的输出将同时出现在变量和屏幕上。

    use Capture::Tiny ':all';
    
    my $stderr, $stdout;
    
    ($stdout, $stderr) = tee {
        system($command);
    };
    

    【讨论】:

    • 谢谢,T 恤很好用。 :) 我希望 Windows 也有替代方案。
    • @ToMmY_hun 它不能在 Windows 上运行吗?我现在没有人可以测试它,但医生说应该。
    • 我还不知道。如果我开始使用它,我会告诉你的。
    【解决方案3】:

    我能想到的简单方法:

    #! /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
    

    【讨论】:

    • 是的,我正在使用 T 恤,它工作正常。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2014-07-22
    • 2012-07-14
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    相关资源
    最近更新 更多