无缓冲输出 - Perl:在运行时打印日志,而不是稍后一次转储所有日志



我有一个从 Jenkins slave 运行的 Perl 脚本。该脚本执行保存在远程盒子 A 上的 shell 脚本。这个 shell 脚本实际上是在机器 A 本身上部署战争的。两台机器,Jenkins 从站和远程盒子都是 CentOS 实例。

use strict;
use warnings;
use Cwd;
use File::Copy;
use Getopt::Long;
use File::Basename;
use Net::OpenSSH;
my ($conf_file, $environment, $doexec, $exec, $job, $dest_file, $user, $host, $IP, $TARGET_SERVER, $JENKINS_JOB, $wrapper, $src_file, $src_path, $src_dist_path, $src_full_path, $id_file, $ssh, @array, $line);
init();
sub init {
    $JENKINS_JOB = $ENV{'JOB_NAME'};
    $conf_file = "/home/ec2-user/SCM/conf/deploy_build.conf";
    open (FH, "<", $conf_file) or die "Cannot open < $conf_file: $!";
    while (<FH>) {
        if ( $_ =~ /b$JENKINS_JOBb/ ) {
            push @array, $_;
        } else {
            next;
        }
    }
    foreach $line (@array) {
        ($job, $src_path, $dest_file, $user, $wrapper) = split(':', $line);
        $id_file = "/home/ec2-user/.ssh/priv_key";
        $ssh = Net::OpenSSH->new($IP, key_path => $id_file, user => $user);
        $ssh->error and die "Couldn't establish SSH connection: ". $ssh->error;
        printf "n";
        if (length $wrapper) {      
            printf "Initiating subroutine for executing wrapper on remote machine...n";
            &exec_wrapper;
        } else {
                printf "*** No wrapper specified ****n";
        }
    }
}

sub exec_wrapper {
    my ($stdout, $errput) = $ssh->capture2("~/release/$wrapper");
    printf "Output: $stdoutn" if $stdout;
    die "Error: $errputn" if $errput;
    printf "nnn";
}

现在的问题是,尽管程序运行良好,但它会在一段时间后打印输出。整个输出在 $stdout 中捕获,然后在稍后转储。由于此作业作为 Jenkins 作业运行,因此最终用户在转储输出之前不知道发生了什么。我想在事件发生时打印每一行(运行时(,而不是等待整个输出存储在变量中并在以后转储。我确实阅读了这篇文章,但我不确定它是否适用于我的情况,如果适用,我该如何实施它。我确实尝试过将$| = 1;放在脚本的顶部。它没有用。然后我尝试在初始化 ssh 对象之前放置它,但它在任何情况下都不起作用。值得一提的是,在我的场景中,效率不是问题。

任何帮助将不胜感激。

我从这个节点得到了一个解决方案。我可以使用以下代码实时打印日志,而不是将输出存储在字符串中并在以后转储。

sub exec_wrapper {
    $ssh->system("~/release/$wrapper");
    $ssh->die_on_error("execution of ~/release/$wrapper failed");
}

我也对其他方法持开放态度。

最新更新