簡體   English   中英

外部進程執行時的回顯進度條,並在完成時采用 STDOUT

[英]Echo progress bar for while external process executing and take STDOUT when it done

如何在外部進程執行時回顯進度條並在完成時捕獲其 STDOUT,僅使用標准模塊。 不使用叉子?

  1. 運行外部進程,例如: @array = `ls -l`;

  2. 在執行時,打印進度條,例如: print '.';

  3. 完成后將進程的 STDOUT 捕獲到數組中

  4. 繼續工作主腳本

我正在閱讀有關IPC::Open2IPC::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM