2013-10-08 249 views
0

我正在编写一个Perl脚本来自动化一些软件安装。在我的perl脚本中运行一个非perl脚本?

在我的脚本中,我运行另一个bash脚本,并将其输出并再次打印。

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

但build.sh脚本需要8分钟,所以我的脚本等待8分钟,脚本完成打印输出的开始。

如何从build.sh程序打印每行,因为它在bash shell中运行?

正如评论下面我用system ("/home/me/build.sh");

但输出变为然而壳我做了我的脚本重定向到我的日志文件,

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

这时应该当我使用的系统功能输出将被重定向到文件名,但它不是。

我应该用print system ("/home/me/build.sh");代替system ("/home/me/build.sh");吗?

的完整代码:

#!/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>); 
} 
+0

尝试加入'$ | ++'在顶部你的脚本 – bhb

+0

这是什么意思? –

+1

它没有重复,因为在这里我在脚本开始时做了输出重定向。 –

回答

6

更灵活的方式是使用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");将打印的system()的返回值,这是你的shell脚本的退出状态,而不是输出想要的。

+1

我有一个问题,'build.sh'会在'while'开始时完成吗? –

+2

@M_E不,他们是两个同时运行的进程。子进程(shell脚本)生成输出并将它们写入管道,并且当有新行时,父进程(perl脚本)从管道获取输出。 –

+0

'open(PIPE,“ - |”,“/home/me/build.sh”); print(while();'这里print将使用'STDOUT'并且我做了输出重定向,但是它仍然在shell上打印,为什么这么做? –

0

如何从build.sh程序打印每行,因为它在bash shell中运行?

可能的解决方案: 你可以尝试以下

系统( “SH /home/me/build.sh |发球文件名”);

上面的语句将显示在控制台上build.sh的输出,并在同一时间写在发球提供作为参数的文件名是输出