Jak wyświetlić liczbę wierszy wyprowadzanych przez polecenie w czasie rzeczywistym?


15

Używam svn exportjako części skryptu programu pakującego dla mojej aplikacji i wygląda na to, że to polecenie, podobnie jak wiele innych, nie ma żadnego paska postępu.

W tej chwili mam dwie możliwości:

  • używając go bez opcji i obserwuj, jak drukuje tysiące linii
  • używając --quieti nie widząc niczego, dopóki się nie zakończy.

Czy istnieje sposób, aby przynajmniej pokazywać liczbę wierszy wyprowadzanych przez polecenie w czasie rzeczywistym? Jak na przykład:

Exporting SVN directory ... 1234 files

I widzisz ten 1234 przyrost liczby w czasie rzeczywistym ? Mogę sobie wyobrazić przesyłanie danych wyjściowych do polecenia, które by to zrobiło, ale które?

Odpowiedzi:


16
yourcommand | { I=0; while read; do printf "$((++I))\r"; done; echo ""; }

Lub umieść sekcję w nawiasach w skrypcie powłoki. Zauważ, że działa to tylko wtedy, gdy twoja powłoka faktycznie obsługuje operatora wstępnego zwiększania, takiego jak bash, ksh93 lub zsh. W przeciwnym razie będziesz musiał zwiększyć, $Ia następnie wydrukować (jak w I=$((I+1));printf...). Ponadto, jeśli printfnie jest wbudowany w twoją powłokę (jest to wbudowany w bieżący bash), możesz użyć echo -nelub print -nzamiast tego dla lepszej wydajności. Chcesz tylko ukryć nowy wiersz i interpretować znak jako znak zmiany znaczenia.


Och, nigdy nie nauczę się bashscripting z wszystkimi jego brzydkimi =różnicami i dziwactwami `=`. :) Dlaczego nie zastąpiliby go językiem składniopodobnym jak python ...
Boris Burkov

Hej, wiem co! Możesz dodać symbol powrotu karetki do każdej nowej linii, którą drukujesz, i nie zaleje ekranu, po prostu nadpisze poprzednią linię.
Boris Burkov

Dlatego printfkończy się na \r. A co się stanie, jeśli to zrobisz echo -ne "$I\r"lub print -n "$I\r". :) Użyłem printfjednak, ponieważ domyślnie nie drukuje nowego wiersza na końcu, więc po \rprostu wraca do początku. Niestety nie wszystkie implementacje echa obsługują argument -elub -n.
dannysauer

1
Działa to również z wersją pdksh, której OpenBSD używa dla / bin / sh.
kurtm

1
+1, choć by być absolutnie poprawnym, powinieneś zmienić readna read -r(ponieważ w przeciwnym razie odwrotny ukośnik na końcu linii zakłóciłby liczenie). Nawiasem mówiąc, przy odrobinie pracy można to dostosować, aby wyświetlać również najnowszą linię danych wyjściowych, co może być przydatne w przypadku niektórych poleceń.
ruakh

7

To trudny pomysł, ale możesz użyć tego pvpolecenia, aby policzyć liczbę linii w ruchu i wyświetlić je na ekranie. pvwśród wielu przełączników znajduje się -lprzełącznik, który zlicza każdą linię w miarę jej przechodzenia.

Przykład

Tutaj używam pętli while do symulacji niektórych plików z wyjścia SVN.

$ for i in $(seq 100); do echo "file$i"; sleep 2; done | pv -l -c >/dev/null
   3 0:00:05 [0.99/s ] [      <=>             

Nadpisuje linię wyjściową w następujący sposób:

  18 0:00:36 [   0/s ] [                                     <=>                                                                  ]

  24 0:00:47 [0.991/s ] [                                                <=>                                                      ]

Nie byłem świadomy pv. Brawo dla nauki!
dannysauer

@dannysauer - pv jest warte spędzenia czasu na nauce, pozwala mierzyć i wyświetlać wszystko, co przechodzi przez rurę.
slm

Zainstalowałem go po przeczytaniu komentarza i bawieniu się nim. Osiemnaście lat używa Linuksa i wciąż są nowe rzeczy do odkrycia. :)
dannysauer,

0

Możesz uruchomić swoje polecenie w tle jako zadanie i przekierować jego stdout (i opcjonalnie stderr) do pliku logu: command > logfile &gdzie &oznacza zadanie (jeśli stderr też, powiedz &>zamiast >).

Następnie możesz użyć narzędzia wordcount, aby policzyć liczbę wierszy w pliku dziennika wc -l.

Aby pokazać zmianę stanu w jednej dynamicznie zmieniającej się linii, możesz użyć czegoś takiego while true; do echo -en '\r'; wc -l logfile; sleep 1; done, ale nie mogę zmusić bash do narysowania \rpowrotu karetki, aby zabić zawartość poprzedniej linii.

Zobacz to pytanie, to prawie duplikat: /programming/2388090/how-to-delete-and-replace-last-line-in-the-terminal-using-bash


1
Ale chce wyświetlacza w czasie rzeczywistym, który stale rośnie, czego nie robi wc.
kurtm

@kurtm eh, tym, czego chce znacznie więcej, nie jest zalanie ekranu wynikami, printf/print/echojak sugeruje Danny. :) Oczywiście, że mógłby skorzystać less, ale przypuszczam, że stać go na to, by powiedzieć wc -l logfileza każdym razem, gdy się niecierpliwi. Myślę, że zabawa ncurseslub wyczyszczenie ekranu to tutaj przesada.
Boris Burkov

No tak. Nie chce, aby został zalany, ale chce poznać postęp, w przeciwnym razie mógłby po prostu użyć --quiet.
kurtm

@kurtm zobacz aktualizację: czy możesz pomóc w debugowaniu mojego echo -e 'r'polecenia? Powinien usunąć poprzednio wydrukowaną zawartość linii, aby dynamicznie się zmieniała, ale nie mogę tego zmusić :(
Boris Burkov,

Chcesz również dodać opcję n do echa, która tłumi końcowy znak nowej linii.
kurtm
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.