Saving more corsor positions (with tput?) in bash terminal

I know that tput sc saves the current cursor position and tput rc restores it exactly where tput sc was called. The problem is that every time tput sc is called, it overwrites the previous saved position.

Is there a way to save more positions, e.g. tput sc pos1 and tput sc pos2 which can be restored with, say, tput rc pos1 and tput rc pos2 respectively? (The solution need not make use of tput, I mentioned it because it's the only command I know that handles cursor position)

If not, is there a way to at least save the cursor position locally in a function, so that if a function uses tput sc and then calls another function that runs again tput sc, then each function restores its own saved cursor position when invoking tput rc?

Thanks in advance.


You can use the following function to extract current cursor position in a simple array:

extract_current_cursor_position () {
    export $1
    exec < /dev/tty
    oldstty=$(stty -g)
    stty raw -echo min 0
    echo -en "\033[6n" > /dev/tty
    IFS=';' read -r -d R -a pos
    stty $oldstty
    eval "$1[0]=$((${pos[0]:2} - 2))"
    eval "$1[1]=$((${pos[1]} - 1))"
}

(the source of code used in this function was taken and adapted from this answer)

Now, for example, to save current cursor position in pos1, use:

extract_current_cursor_position pos1

To save current cursor position in pos2, use:

extract_current_cursor_position pos2

To see cursor positions saved in pos1 and pos2, you can use:

echo ${pos1[0]} ${pos1[1]}
echo ${pos2[0]} ${pos2[1]}

To move/restore cursor position to pos1, you have to use:

tput cup ${pos1[0]} ${pos1[1]}

To move/restore cursor position to pos2, you have to use:

tput cup ${pos2[0]} ${pos2[1]}

tput command works through terminal control sequences, listed here: http://sydney.edu.au/engineering/it/~tapted/ansi.html There is a sequence for extracting current position (Query Cursor Position - \e[6n) and looks like it's not present in tput. To extract it use:

stty -echo; echo -n $'\e[6n'; read -d R x; stty echo; echo ${x#??}
30;1

Now you can extract row position saved in $x to some other variable and move your cursor using tput cup later:

$ echo $my_saved_pos
12
$ tput cup $my_saved_pos 0