Przyjazny dla zasobów sposób sygnalizowania programowi użytkownika nie zawiesza się

10

Mam skrypt Perla w systemie * nix, który w pewnym momencie przetwarza ponad 50 000 linii tekstu. To zajmuje trochę czasu. Próbuję znaleźć sposób przyjazny dla zasobów, aby użytkownik wiedział, że program się nie zawiesza, gdy przetwarza cały ten tekst.

Obecnie drukuję dane wyjściowe w czasie rzeczywistym, gdy tekst jest przetwarzany. Opróżniam bufor wyjściowy, a następnie drukuję dane wyjściowe w jednym wierszu za pomocą \r. Wydaje się to być niepotrzebnym wykorzystaniem zasobów, ponieważ zajmuje prawie dwa razy więcej czasu niż wtedy, gdy nic nie drukuję, ale jak już powiedziałem, podczas drukowania nic nie wygląda na to, że program się zawiesił.

Więc moje pytanie: czy istnieje standardowy lub prosty sposób, aby poinformować użytkownika, że ​​program rzeczywiście działa podczas wykonywania długich zadań?

BryanK
źródło
Który unix? Jeśli jest to FreeBSD, możesz sprawdzić, czy nadal jest zajęty, wysyłając Control-T (co jest domyślnym poleceniem Status ).
Hennes

Odpowiedzi:

6

[Właśnie realizowany jest skrypt Perl , ale ta sama logika ma zastosowanie print "\r", itd. Będziemy chcieli, aby użyć STDERRalbo kolej off buforowania $| = 1. Zobacz na dole.]

Jednym ze sposobów implementacji „wskaźnika postępu” interfejsu CLI jest użycie \rznaku (powrót karetki). Sprowadza to kursor na początek bieżącej linii:

#!/bin/bash

count=0
while ((1)); do
    echo -ne "\rCount: $count"
    sleep 1;
    count=$(($count+1));
done     

Jeśli to nie ma sensu, po prostu spróbuj.

Możesz użyć tej techniki, aby wskazać, ile linii lub tysiące linii zostało przetworzonych do tej pory. Dziesiątki lub setki linii mogą być dobre, ponieważ nie jest to zbyt często (więcej aktualizacji == wolniejszy czas działania), ale prawdopodobnie wciąż wystarczająco często, aby pokazać postęp. Możesz podać jednostkę lub po prostu dodać zera.

Zwróć uwagę na użycie -ni -ez echo, to jest ważne.

Możesz także użyć \b(backspace), aby uzyskać podobny efekt.


W perlu:

#!/usr/bin/perl
use strict;
use warnings FATAL => qw(all);

$| = 1;  # Pipeline stdout (i.e., no buffering).

my $count = 1;
while ($count) {
    print "\rCount $count";
    sleep 1;
    $count++;
}               
Złotowłosa
źródło
3

Wydrukuj pojedynczy .bez echa nowej linii podczas przetwarzania. Starsza technika.

Otrzymujesz:

Processing...............

Prosty i skuteczny.

kurtm
źródło