Подтвердить что ты не робот

Как удалить и заменить последнюю строку в терминале с помощью bash?

Я хочу реализовать индикатор выполнения, показывающий прошедшие секунды в bash. Для этого мне нужно удалить последнюю строку, показанную на экране (команда "clear" стирает весь экран, но мне нужно удалить только строку индикатора выполнения и заменить ее новой информацией).

Конечный результат должен выглядеть так:

$ Elapsed time 5 seconds

Затем через 10 секунд я хочу заменить это предложение (в том же положении на экране):

$ Elapsed time 15 seconds
4b9b3361

Ответ 1

повторите возврат каретки с помощью \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

Ответ 2

Возвращение каретки только перемещает курсор в начало строки. Это нормально, если каждая новая строка вывода не меньше, чем предыдущая, но если новая строка короче, предыдущая строка не будет полностью перезаписана, например:

$ echo -e "abcdefghijklmnopqrstuvwxyz\r0123456789"
0123456789klmnopqrstuvwxyz

Чтобы действительно очистить строку для нового текста, вы можете добавить \033[K после \r:

$ echo -e "abcdefghijklmnopqrstuvwxyz\r\033[K0123456789"
0123456789

http://en.wikipedia.org/wiki/ANSI_escape_code

Ответ 3

Ответ Derek Veit работает хорошо, если длина линии никогда не превышает ширину терминала. Если это не так, следующий код предотвратит нежелательный вывод:

прежде чем строка будет записана в первый раз, do

tput sc

который сохраняет текущую позицию курсора. Теперь, когда вы хотите распечатать свою строку, используйте

tput rc
tput ed
echo "your stuff here"

чтобы сначала вернуться к сохраненной позиции курсора, затем очистить экран от курсора до нижней части и, наконец, записать вывод.

Ответ 4

Метод\033 не работал у меня. Метод \r работает, но на самом деле ничего не стирает, просто помещает курсор в начало строки. Поэтому, если новая строка короче старой, вы можете увидеть оставшийся текст в конце строки. В конце концов, tput был лучшим способом. У него есть другие возможности, помимо материала курсора, плюс он поставляется с предустановленной во многих дистрибутивах 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

Здесь немного обратного отсчета script, чтобы играть с:

#!/bin/bash
timeout () {
    tput sc
    time=$1; while [ $time -ge 0 ]; do
        tput rc; tput el
        printf "$2" $time
        ((time--))
        sleep 1
    done
    tput rc; tput ed;
}

timeout 10 "Self-destructing in %s"

Ответ 5

Используйте символ возврата каретки:

echo -e "Foo\rBar" # Will print "Bar"

Ответ 6

В случае, если выход прогресса является многострочным, или script уже напечатал новый символ строки, вы можете перепрыгнуть строки с чем-то вроде:

printf "\033[5A"

который заставит курсор прыгать на 5 строк вверх. Затем вы можете перезаписать все, что вам нужно.

Если это не сработает, вы можете попробовать printf "\e[5A" или echo -e "\033[5A", который должен иметь тот же эффект.

В принципе, с escape-последовательностями вы можете контролировать почти все на экране.

Ответ 7

Самый простой способ - использовать символ \r, который я предполагаю.

Недостатком является то, что вы не можете иметь полные строки, поскольку он очищает только текущую строку.

Простой пример:

time=5
echo -n "Elapsed $time seconds"
sleep 10
time=15
echo -n "Elapsed $time seconds"

echo "\nDone"