我正在编写一个Perl脚本来自动化一些软件安装.
在我的脚本中,我运行另一个bash脚本并获取其输出并再次打印它.
print `/home/me/build.sh`;
Run Code Online (Sandbox Code Playgroud)
但build.sh脚本需要8分钟,所以我的脚本等到8分钟,脚本完成打印输出的开始.
如何在build.sh程序中打印每一行,因为它在bash shell中运行?
正如下面的评论我使用 system ("/home/me/build.sh");
但输出转到shell但是我在我的脚本中重定向到我的日志文件,
open $fh, "> filename";
*STDOUT = $fh;
*STDERR = $fh;
Run Code Online (Sandbox Code Playgroud)
那么当我使用系统功能时,它的输出将被重定向到文件名,但事实并非如此.
我应该用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>);
}
Run Code Online (Sandbox Code Playgroud)
更灵活的方式是使用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;
Run Code Online (Sandbox Code Playgroud)
BTW,print system ("/home/me/build.sh");将打印返回值system(),这是shell脚本的退出状态,而不是所需的输出.