Perl: print log at runtime, instead of dumping everything at once
I have a Perl script that is running from a Jenkins slave. The script executes a shell script stored on remote field A. This shell script actually deploys the war to machine A. Both machines, slave and remote Jenkins panel are CentOS instances.
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_JOB\b/ ) {
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: $stdout\n" if $stdout;
die "Error: $errput\n" if $errput;
printf "\n\n\n";
}
Now the problem is that although the program runs fine, it prints the output after a while. All output is committed to $ stdout and then dumped later. Since this job runs like a Jenkins job, the end user has no idea what happens before the data is output. I wanted to print each line as the event occurs (runtime) rather than waiting for all the output to be stored in a variable and dumped later. I've read this article but I'm not sure if it is relevant to my case and if so how can I implement it. I tried to put$| = 1;
at the top of my script. It didn't work. Then I tried to place it just before initializing the ssh object, but it didn't work in any of the cases. Simply put, efficiency is not a concern in my scenario.
Any help would be really appreciated.
source to share
I got the solution from this node. Instead of storing the output on a line and dumping it later, I can use the following code to print the log in real time.
sub exec_wrapper {
$ssh->system("~/release/$wrapper");
$ssh->die_on_error("execution of ~/release/$wrapper failed");
}
I am also open to other approaches.
source to share