0

I am writing a Perl script to automate some software installation.

In my script I run another bash script and take its output and print it again.

print `/home/me/build.sh`;

but build.sh script take 8 minutes, so my script wait till the 8 minutes and script finishes the starting in printing the output.

How can I print each line from the build.sh program as it is running in bash shell?

As the comment below I use system ("/home/me/build.sh");

but the output goes to shell however I make out redirection in my script to my log file,

open $fh, "> filename";
*STDOUT = $fh;
*STDERR = $fh;

Then should when I use system function its output will be redirected to filename, but it isn't.

Should I use print system ("/home/me/build.sh"); instead of system ("/home/me/build.sh");?

#

The full code:

#!/usr/bin/perl

use strict;
use warnings;

use IO::File;

my %DELIVERIES = ();
my $APP_PATH = $ENV{HOME};
my $LOG_DIR = "$APP_PATH/logs";
my ($PRG_NAME) = $0 =~ /^[\/.].*\/([a-zA-Z]*.*)/;

main(@argv);

sub main
{
        my @comps = components_name();
        my $comp;
        my $pid;

        while ( scalar @comps ) {
                $comp = pop @comps;
                if ( ! ($pid = fork) ) {
                        my $filename = lc "$LOG_DIR/$comp.log";

                        print "$comp delpoyment started, see $filename\n";

                        open (my $logFile, ">", "$filename") or (die "$PRG_NAME: $!" && exit);
                        *STDOUT = $logFile;
                        *STDERR = $logFile;

                        deploy_component ( $comp );

                        exit 0;
                }
        }
        my $res = waitpid (-1, 0);
}


sub components_name
{
        my $FILENAME="$ENV{HOME}/components";
        my @comps = ();

        my $fh = IO::File->new($FILENAME, "r");

        while (<$fh>)
        {
                push (@comps, $1) if /._(.*?)_.*/;
                chomp ($DELIVERIES{$1} = $_);
        }

        return @comps;
}

sub deploy_component
{
        my $comp_name = shift;

        print "\t[umask]: Changing umask to 007\n";
        `umask 007`;

        print "\t[Deploing]: Start the build.sh command\n\n";
        open (PIPE, "-|", "/build.sh");
        print while(<PIPE>);
}
Mahmoud Emam
  • 1,447
  • 4
  • 18
  • 35

2 Answers2

6

A more flexible way is to use pipe.

open PIPE, "/home/me/build.sh |";
open FILE, ">filename";
while (<PIPE>) {
    print $_;           # print to standard output
    print FILE $_;      # print to filename
}
close PIPE;
close FILE;

BTW, print system ("/home/me/build.sh"); will print the return value of system(), which is the exit status of your shell script, not the output wanted.

Logan Ding
  • 1,741
  • 1
  • 12
  • 23
0

How can I print each line from the build.sh program as it is running in bash shell?

Possible Solution: You can try the following

system ("sh /home/me/build.sh | tee fileName");

The above statement will show the output of build.sh on the console and at the same time write that output in the filename provided as the argument for tee

Jayesh Elamgodil
  • 1,437
  • 11
  • 15