Предотвратите мигание текста/экрана при выполнении ясный

На самом деле это не ищет нигде. Это ожидает входа от стандартного входа.

Попробуйте это:

beast:~ viroos$ grep foo

когда Вы вводите строку, содержащую "нечто", и совершаете нападки, входят, эта строка будет повторена иначе, курсор будет перемещен в новую строку, но grep ничего не распечатает.

11
30.06.2013, 00:26
4 ответа

Мигание происходит потому, что скрипт очищает весь экран. Если он закрашивает существующий текст и очищает только по мере необходимости, то мерцания не будет.

Вот пример:

#!/bin/sh
watchit() {
    HOME=$(tput cup 0 0)
    ED=$(tput ed)
    EL=$(tput el)
    ROWS=$(tput lines)
    COLS=$(tput cols)
    printf '%s%s' "$HOME" "$ED"
    while true
    do
        CMD="$@"
        ${SHELL:=sh} -c "$CMD" | head -n $ROWS | while IFS= read LINE; do
            printf '%-*.*s%s\n' $COLS $COLS "$LINE" "$EL"
        done
        printf '%s%s' "$ED" "$HOME"
        sleep 1
    done
}

watchit top -b -n 1

Он делает это:

  • печатает выходные данные заданной команды, которые будут помещаться на экране (без переноса или прокрутки)
  • записывает поверх существующих строк, очищая часть каждой строки, которая не перезаписывается
  • , использует возможность ed вашего терминала для печати из текущего местоположения в конец экрана.

Если вы хотите обработать экран с изменяемым размером, вы можете переместить назначения в ROWS и COLS внутри внешнего цикла, например,

#!/bin/sh
watchit() {
    HOME=$(tput cup 0 0)
    ED=$(tput ed)
    EL=$(tput el)
    printf '%s%s' "$HOME" "$ED"
    while true
    do
        ROWS=$(tput lines)
        COLS=$(tput cols)
        CMD="$@"
        ${SHELL:=sh} -c "$CMD" | head -n $ROWS | while IFS= read LINE; do
            printf '%-*.*s%s\n' $COLS $COLS "$LINE" "$EL"
        done
        printf '%s%s' "$ED" "$HOME"
        sleep 1
    done
}

watchit top -b -n 1

, потому что tput запрашивает текущий размер экрана из системы.

Дальнейшее чтение:

8
27.01.2020, 19:57

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

# You may want to do this if your code is in a script.
unhide_cursor() {
    printf '\e[?25h'
}
trap unhide_cursor EXIT

# Hide the cursor (there is probably a much better way to do this)
printf '\e[?25l'
clear 
while true ; do
    # Move the cursor to the top of the screen but don't clear the screen
    printf '\033[;H' 
    do_a_lot_of_output_here
    sleep 1
done

Этот сценарий оставит артефакты, если Ваш вывод уменьшится. Это, также очень вероятно, не будет портативно. Я только протестировал его с urxvt, xterm, и Св.

6
27.01.2020, 19:57
  • 1
    В этом случае курсор начинает переходить в конец вывода от случайного положения (и артефакты, конечно). Также я попробовал tput clear с теми же результатами (мигающий) –  ravnur 30.06.2013, 00:31
  • 2
    я добавил несколько строк к сценарию для сокрытия курсора. –   30.06.2013, 00:40
  • 3
    Никакой курсор - никакой переход. Но об артефактах? Вывод имеет случайную сумму строк. Я должен заполнить весь сценарий пробелами прежде, чем запустить новый вывод? Но, так или иначе, спасибо за внимание и усилия: +1 от меня для этого, но это не решает мою проблему –  ravnur 30.06.2013, 01:08
  • 4
    я нашел только один способ избавиться от всех артефактов: tput ed. Но это вызывает мигающий –  ravnur 30.06.2013, 01:33
  • 5
    Какой эмулятор терминала Вы используете? С tput ed прямо перед do_a_lot... строка, я вижу мигание в urxvt, но не xterm или Св. –   30.06.2013, 03:18

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

while :; do
   output=$(do_a_lot_of_output_here)
   clear
   echo "$output"
   sleep 1
done

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

9
27.01.2020, 19:57

В качестве расширения ответа Кристиана я создал следующую функцию bash, которая работает, если окно консоли меньше, чем вывод команды:

function watcher()
{
    lines=$(tput lines)
    while true; do
        output="$($@ | head -n $lines)"
        clear
        echo -e "$output"
        sleep 2
    done
}

Это позволяет передавать любую команду наблюдателю. Если вы используете git, используйте git config --global color.status always , а затем:

watcher git status

Будет отображать постоянно обновляемый вывод статуса git.

1
27.01.2020, 19:57

Теги

Похожие вопросы