Tak więc, gdy wget
pobiera stronę internetową, pokazuje pasek stanu wskazujący, ile plików jest / są pobierane. To wygląda tak:
25%[=============>______________________________________] 25,000 100.0K/s
(podkreślenia są spacjami; po prostu nie mogłem wymyślić, jak uzyskać tam więcej niż jedno kolejne pole)
Jednak zamiast pisać kolejną linię na standardowe wyjście i dodawać kolejny pasek postępu, aktualizuje go w następujący sposób:
50%[===========================>________________________] 50,000 100.0K/s
I wget
nie jest to jedyny przykład tego. Na przykład, kiedy wpinasz coś do, less
a następnie kończysz, twój oryginalny monit jest nadal wyświetlany, wraz z wynikiem wszelkich wcześniejszych poleceń. To tak, jakbyś nigdy nie wyszedł.
Tak więc moje pytania brzmią: jak to się nazywa, jak to zaimplementować, czy działa tylko dla pojedynczej linii na raz i czy mogę tego użyć w C?
Odpowiedzi:
Przede wszystkim twoje pytanie nie ma nic wspólnego z bash, ale z terminalem. Terminal odpowiada za wyświetlanie tekstu programów, a sam bash nie ma kontroli nad programami po ich uruchomieniu.
Terminale oferują sekwencje kontrolne do sterowania kolorem, czcionką, pozycją kursora i nie tylko. Lista standardowych sekwencji terminali znajduje się na stronie http://www.termsys.demon.co.uk/vtansi.htm Możesz na przykład
aby utworzyć pasek postępu.
Bardziej zaawansowane sekwencje specjalne terminali są zazwyczaj zależne od terminali, np. Działają tylko z Eterm lub Xterm. ncurses - to biblioteka programistyczna do tworzenia interaktywnych programów za pomocą terminala, dzięki czemu nie musisz używać sekwencji specjalnych.
Jak zastąpić istniejącą linię sekwencjami końcowymi
Jak zastąpić istniejącą linię bez sekwencji terminali
Jednym prostym rozwiązaniem jest nie pisanie nowego wiersza na końcu, ale zapisanie znaku powrotu karetki, co w zasadzie resetuje kursor do początku linii, np .:
Znak
\r
powrotu karetki umieści kursor na początku wiersza i umożliwi zastąpienie zawartości wiersza.Przełączaj między buforami, takimi jak
less
lubvi
Zachowanie
less
jest również spowodowane bardziej zaawansowaną funkcją terminalu, alternatywnym ekranem:http://rosettacode.org/wiki/Terminal_control/Preserve_screen zawiera kilka przykładów, jak to zrobić samemu, albo przez tput , albo za pomocą sekwencji specjalnych.
źródło
Zamiast używać,
echo
który automatycznie dodaje nową linię do łańcucha, użyjprintf "%s\r" whatever
- powrót karetki przesyła kursor na początek bieżącej linii. przykład:źródło
printf "\r%2d " $num