什么时候脚本的输出被附加到文件,我该怎么做才能绕过结果呢?

时间:2013-12-20 14:45:26

标签: perl bash shell

我有一个名为my_bash.sh的脚本,它调用perl脚本,并将perl脚本的输出附加到日志文件中。只有在perl脚本完成后才能写入文件吗?

my_bash.sh

#!/bin/bash
echo "Starting!" > "my_log.log"
perl my_perl.pl >> "my_log.log" 2>&1
echo "Ending!" >> "my_log.log"

问题是,当perl脚本正在运行时,我想在my_log.log文件运行时操作它,但看起来该文件是空白的。有没有正确的方法来做到这一点?如果您想了解更多信息,请与我们联系。

my_perl.pl

...
foreach $component (@arrayOfComponents)
{
  print "Component Name: $component (MORE_INFO)\n";

  # Do some work to gather more info (including other prints)
  #...

  # I want to replace "MORE_INFO" above with what I've calculated here
  system("sed 's/MORE_INFO/$moreInfo/' my_log.log");
}

sed无法正常运行,因为print语句尚未进入my_log.log

4 个答案:

答案 0 :(得分:2)

此问题的答案取决于my_perl.pl输出数据的方式以及输出的数据量。

如果您使用普通(缓冲)I / O来产生输出,那么只有在STDOUT缓冲区填充后才会写入my_log.log。一般来说,如果你没有产生大量的输出,那就是程序结束并刷新缓冲区。

如果您正在产生足够的输出来填充输出缓冲区,那么在my_log.log完成之前,您将在my_perl.pl中获得输出。

此外,在Perl中,您可以使用以下代码使STDOUT无缓冲:

select STDOUT; $| = 1;

在这种情况下,您的输出将在脚本中生成的那一刻写入STDOUT(然后通过重定向写入my_log.log

答案 1 :(得分:2)

默认情况下,Perl会缓冲输出。禁用缓冲集$|为非零值。添加

$|++;

位于perl脚本的顶部。

引用perldoc pervar

  

$|

     

如果设置为非零,则立即强制刷新并在每次写入或之后   在当前选定的输出通道上打印。默认值为0   (无论通道是否真的由系统缓冲或   不; $|仅告诉您是否已明确要求Perl进行刷新   每次写完后)。如果输出为STDOUT,通常会进行行缓冲   到终端和否则缓冲块。设置此变量是   主要用于输出管道或插槽时,例如   当您在rsh下运行Perl程序并想要查看时   输出正在发生。这对输入缓冲没有影响。看到   getc为此。请参阅有关如何选择输出通道的选择。看到   还有IO :: Handle。

     

助记符:当你想让你的烟斗滚烫时。

答案 2 :(得分:0)

根据您需要对日志文件执行的操作,谁可以从perl脚本读取每行输出,对该行执行某些操作,然后自己(或不)将其写入日志:

#!/bin/bash
echo "Starting!" > "my_log.log"
perl my_perl.pl | \
while read line; do
    # do something with the line
    echo "$line" >> "my_log.log"
done
echo "Ending!" >> "my_log.log"

答案 3 :(得分:0)

介于两者之间

print "Component Name: $component (MORE_INFO)\n";

system("sed 's/MORE_INFO/$moreInfo/' my_log.log");
你打印东西吗?如果没有,请延迟第一次打印,直至找到$moreInfo

my $header = "Component Name: $component (MORE_INFO)";
# ...
# now I have $moreInfo
$header =~ s/MORE_INFO/$moreInfo/;
print $header, "\n";

如果你打印东西,你可以随时“排队”它,直到你得到你需要的信息:

my @output;
foreach my $component (...) {
    @output = ("Component Name: $component (MORE_INFO)");
    # ...
    push @output, "something to print"; 
    # ...
    $output[0] =~ s/MORE_INFO/$moreInfo/;
    print join("\n", @output), "\n";