I\'m trying to create an update-able progress status. In order to do that, I need to be able to clear the last output in its entirety so that I can update it. Carriage retur
Inspired by How to get the cursor position in bash?
#!/bin/bash
lineformat="This is a very long line with a lot of stuff so they will take "
lineformat+="more than standard terminal width (80) columns... Progress %3d%%"
n=0
while [[ $n -ne 100 ]]; do
n=$((n+1))
printf -v outputstring "$lineformat" $n
twidth=$(tput cols) # Get terminal width
theight=$(tput lines) # Get terminal height
oldstty=$(stty -g) # Save stty settings
stty raw -echo min 0 # Suppres echo on terminal
# echo -en "\E[6n"
tput u7 # Inquire for cursor position
read -sdR CURPOS # Read cursor position
stty $oldstty # Restore stty settings
IFS=\; read cv ch <<<"${CURPOS#$'\e['}" # split $CURPOS
uplines=$(((${#outputstring}/twidth)+cv-theight))
((uplines>0)) &&
tput cuu $uplines # cursor up one or more lines
tput ed # clear to end of screen
tput sc # save cursor position
echo -n "$outputstring"
tput rc # restore cursor
sleep .0331s
done
echo
As tput cols and tput lines is initiated at each loop, you could resize window while running, cuu argument will be re-computed.
trap WINCH for querying terminal size only when window is resized newlines for scrolling up before cuutputThere:
#!/bin/bash
lineformat="This is a very long line with a lot of stuff so they will take "
lineformat+="more than standard terminal width (80) columns... Progress %3d%%"
getWinSize() {
{
read twidth
read theight
} < <(
tput -S - <<<$'cols\nlines'
)
}
trap getWinSize WINCH
getWinSize
getCpos=$(tput u7)
getCurPos() {
stty raw -echo min 0
echo -en "$getCpos"
read -sdR CURPOS
stty $oldstty
IFS=\; read curv curh <<<"${CURPOS#$'\e['}"
}
oldstty=$(stty -g)
before=$(tput -S - <<<$'ed\nsc')
after=$(tput rc)
n=0
while [[ $n -ne 100 ]]; do
n=$((n+1))
printf -v outputstring "$lineformat" $n
getCurPos
uplines=$(((${#outputstring}/twidth)+curv-theight))
if ((uplines>0)) ;then
printf -v movedown "%${uplines}s" ''
echo -en "${movedown// /\\n}"
tput cuu $uplines
fi
printf "%s%s%s" "$before" "$outputstring" "$after"
sleep .05
done
downlines=$((${#outputstring}/twidth))
printf -v movedown "%${downlines}s" ''
echo "${movedown// /$'\n'}"