[英]Echo progress bar for while external process executing and take STDOUT when it done
如何在外部進程執行時回顯進度條並在完成時捕獲其 STDOUT,僅使用標准模塊。 不使用叉子?
運行外部進程,例如: @array = `ls -l`;
在執行時,打印進度條,例如: print '.';
完成后將進程的 STDOUT 捕獲到數組中
繼續工作主腳本
我正在閱讀有關IPC::Open2
、 IPC::Open3
的信息,但我不明白如何將它們用於此任務。 也許這不是正確的方向?
到目前為止你有什么? 如果您在進程間通信方面遇到問題,請暫時忘記進度條並詢問一下。
對於具有不確定結束的事物,您真的不能有進度條。 如果你不知道你會讀多少輸入,你就不知道你讀了多少。 人們傾向於將進度條視為已完成工作的一部分,而不是活動。 也就是說,除非您使用 macOS 並理解“不到一分鍾”意味着“超過三個小時”。 ;)
我傾向於做一些簡單的事情,我 output 每隔一段時間就一個點。 我不知道我會看到多少點,但我知道我會看到新的。
$|++; # unbuffer stdout to see dots as they are output
while( <$fh> ) {
print '.' if $. % $chunk_size; # $. is the line number
print "\n[$.] " if $. % $chunk_size * $row_length;
...
}
$fh
可以是您想要讀取的任何內容,包括 pipe。 perlopentut有從外部進程讀取的示例。 不過,那些正在分叉。 而且,其他模塊也將分叉。 是什么限制讓你認為你不能使用 fork?
您可以通過使用curses 和其他東西(回車很方便:)來使您的顯示更加精美,但我不傾向於將它們打出來。
也許 OP 正在尋找下一種東西,只是為了表明外部進程正在運行。
為$SIG{ALRM}
定義一個處理程序並將alarm 1
設置為每秒運行一次處理程序。 處理完成后,重置alarm 0
以關閉警報處理程序。
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my $ls_l; # variable to store output of external command
$| = 1; # unbuffered output
$SIG{ALRM} = \&handler;
alarm 1; # run handler every second
say 'Running sig_alarm_sleep';
$ls_l=`./sig_alarm_sleep`;
say ' done';
alarm 0;
my @fields = qw(rwx count user group size month day time name);
my @lines = split("\n",$ls_l);
my(@array);
for( @lines ) {
my $x->@{@fields} = split(' ',$_);
push @array, $x;
}
say Dumper(@array);
exit 0;
sub handler {
print '.';
$SIG{ALRM} = \&handler;
alarm 1;
}
Bash 腳本sig_alarm_sleep
示例
#!/usr/bin/bash
sleep 20
ls -al
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.