Как удалить и заменить последнюю строку в терминале с помощью bash?
Я хочу, чтобы реализовать прогресс-бар, показывающий время в секундах, прошедшее в bash. Для этого мне нужно стереть последнюю строку, показанную на экране (команда "очистить" стирает весь экран, но мне нужно стереть только строку индикатора выполнения и заменить ее новой информацией).
конечный результат должен выглядеть так:
$ Elapsed time 5 seconds
затем через 10 секунд я хочу заменить это предложение (в том же положении на экране):
$ Elapsed time 15 seconds
8 ответов:
Эхо возврат каретки с \r
seq 1 1000000 | while read i; do echo -en "\r$i"; done
от человека Эхо:
-n do not output the trailing newline -e enable interpretation of backslash escapes \r carriage return
возврат каретки само по себе только перемещает курсор в начало строки. Это нормально, если каждая новая строка вывода по крайней мере такая же длинная, как и предыдущая, но если новая строка короче, предыдущая строка не будет полностью перезаписана, например:
$ echo -e "abcdefghijklmnopqrstuvwxyz\r0123456789" 0123456789klmnopqrstuvwxyz
чтобы на самом деле очистить строку для нового текста, вы можете добавить
3[K
после\r
:$ echo -e "abcdefghijklmnopqrstuvwxyz\r3[K0123456789" 0123456789
ответ Дерека Вайта работает хорошо, пока длина линии никогда не превышает ширину терминала. Если это не так, то следующий код предотвратит вывод нежелательной информации:
прежде чем строка будет написана в первый раз, сделайте
tput sc
, который сохраняет текущую позицию курсора. Теперь, когда вы хотите напечатать свою строку, используйте
tput rc tput ed echo "your stuff here"
чтобы сначала вернуться в сохраненное положение курсора, затем очистить экран от курсора вниз и, наконец, написать выход.
метод \033 не работал для меня. Метод \r работает, но на самом деле ничего не стирает, просто помещает курсор в начало строки. Поэтому, если новая строка короче старой, вы можете увидеть оставшийся текст в конце строки. В конце концов tput был лучшим способом пойти. Он имеет другие применения, кроме курсора stuff plus он поставляется предварительно установленным во многих дистрибутивах Linux & BSD, поэтому он должен быть доступен для большинства пользователей bash.
#/bin/bash tput sc # save cursor printf "Something that I made up for this string" sleep 1 tput rc;tput el # rc = restore cursor, el = erase to end of line printf "Another message for testing" sleep 1 tput rc;tput el printf "Yet another one" sleep 1 tput rc;tput el
вот небольшой обратный отсчет скрипт для игры с:
#!/bin/bash timeout () { tput sc time=; while [ $time -ge 0 ]; do tput rc; tput el printf "" $time ((time--)) sleep 1 done tput rc; tput ed; } timeout 10 "Self-destructing in %s"
в случае, если вывод прогресса является многострочным, или сценарий уже напечатал бы новый символ строки, вы можете перейти к строкам с чем-то вроде:
printf "3[5A"
который сделает курсор, чтобы перейти 5 строк вверх. Тогда вы можете перезаписать все, что вам нужно.
Если это не сработает, вы можете попробовать
printf "\e[5A"
илиecho -e "3[5A"
, который должен иметь тот же эффект.в основном, с escape-последовательности вы можете контролировать практически все на экране.