如何在外部行程執行時回顯進度條并在完成時捕獲其 STDOUT,僅使用標準模塊。不使用叉子?
運行外部行程,例如:
@array = `ls -l`;在執行時,列印進度條,例如:
print '.';完成后將行程的 STDOUT 捕獲到陣列中
繼續作業主腳本
我正在閱讀IPC::Open2, IPC::Open3,但我不明白如何將它們用于此任務。也許這不是正確的方向?
uj5u.com熱心網友回復:
到目前為止你有什么?如果您在行程間通信方面遇到問題,請暫時忘記進度條并詢問一下。
對于具有不確定結束的事物,您真的不能有進度條。如果你不知道你會讀多少輸入,你就不知道你讀了多少。人們傾向于將進度條視為已完成作業的一部分,而不是活動。也就是說,除非您使用 macOS 并理解“不到一分鐘”意味著“超過三個小時”。;)
我傾向于做一些簡單的事情,我經常輸出一個點。我不知道我會看到多少點,但我知道我會看到新的。
$| ; # 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可以是您想要讀取的任何內容,包括管道。perlopentut有從外部行程讀取的示例。不過,那些正在分叉。而且,其他模塊也將分叉。是什么限制讓你認為你不能使用 fork?
您可以通過使用詛咒和其他東西來獲得更多的顯示效果(回車很方便:),但我不傾向于輸入這些內容。
uj5u.com熱心網友回復:
也許 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/425561.html
標籤:perl
上一篇:Perl按值的值對哈希進行排序
