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#??}

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
$ tput cup $my_saved_pos 0

tput was mentioned with a ?, so consider ANSI codes movement codes:

  • $'\e[s' - Saves current position
  • $'\e[u' - Restores previous position


$ printf "\e[s\e[6CWORLD\e[uHELLO\n"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.