rkmax
rkmax

Reputation: 18133

Double buffer on bash

I have a script with a loop printing info every N seconds

function exit_loop
{
    tput rmcup
    tput cnorm
    exit 0
}

function main_loop
{
    tput smcup
    tput civis

    trap exit_loop SIGINT

    while [ true ]; do
        sleep $DELAY &
        clear
        # do things and print
        wait
    done
}

the previous work fine but when the script is printing is ugly between refesh, exist some kind of double buffer.

Note

my script use colors in output with echo -e and printf sentences

Upvotes: 0

Views: 766

Answers (2)

0x777C
0x777C

Reputation: 1047

You can implement double buffering in bash by creating a custom function to replace your printf or echo calls which stores the text you want to display on the screen. This will prevent any issues with your program flickering. Here's what I use for my program:

front_buffer=""
back_buffer="$front_buffer"
draw_text() {
        front_buffer="${front_buffer}${1}"
}
render() {
        previous_height=$(printf "$back_buffer" | fold -s -w "$terminal_columns" | wc -l)
        new_height=$(printf "$front_buffer" | fold -s -w "$terminal_columns" | wc -l)

        #clear the screen entirely if the height has changed to avoid leaving artifacts behind
        if [ "${previous_height}" -ne "${new_height}" ]; then
                printf "$(clear)${front_buffer}"
        else
                printf "$(tput cup 0 0)${front_buffer}"
        fi
        back_buffer="${front_buffer}"
        front_buffer=""
}

Upvotes: 0

Mark Reed
Mark Reed

Reputation: 95267

The closest thing to a double-buffer is rici's answer: do all your # do things and print stuff with output redirected into a temp file, before you clear the screen; then clear the screen and cat the temp file.

Or you can move the cursor to the top of the screen without clearing it and then overwrite what's there. However, then you're responsible for clearing out any remaining old text that extended past the end of the new text.

Upvotes: 0

Related Questions