How do you backspace the line you just wrote with bash and put a new one over its spot? I know it's possible, Aptitude (apt-get) use it for some of the updating stuff and it looks great.
Try this:
$ printf "12345678\rABC\n"
ABC45678
As you can see, outputting a carriage return moves the cursor to the beginning of the same line.
You can clear the line like this:
$ printf "12345678\r$(tput el)ABC\n"
ABC
Using tput
gives you a portable way to send control characters to the terminal. See man 5 terminfo
for a list of control codes. Typically, you'll want to save the sequence in a variable so you won't need to call an external utility repeatedly:
$ clear_eol=$(tput el)
$ printf "12345678\r${clear_eol}ABC\n"
ABC
echo -e '\033[1mbold\033[0m\033[4memphasis\033[0m'
) –
Stalky It's not really clear to me what you want, but, depending on your terminal settings you can print ^H (control H) to the screen and that will back the cursor up one position.
Also note that some terminals have the ability to move the cursor to the beginning of the line, in which case you'd move to the beginning of the line, print enough spaces to overwrite the entire line (Usually available from $COLUMNS) and then print any message or whatever.
If you clarify exactly what you want and I can answer you I'll update my answer.
Here's an example using the find command & a while-read loop to continually print full file paths to stdout on a single line only:
command find -x / -type f -print0 2>/dev/null | while read -d $'\0' filename; do
let i+=1
filename="${filename//[[:cntrl:]]/}" # remove control characters such as \n, \r, ...
if [[ ${#filename} -lt 85 ]]; then
printf "\r\e[0K\e[1;32m%s\e[0m %s" "${i}" "${filename}"
else
printf "\r\e[0K\e[1;32m%s\e[0m %s" "${i}" "${filename:0:40}.....${filename: -40}"
fi
done; echo
The original question was for an animated progress bar (in apt-get) but it appears that nobody really answered that original question.
Either way I wrote this a bit of code a little while ago based on the top answer to this StackOverflow Thread. There are many beautifully complicated progress bars, but none of them "count-down" or "disappearing" progress bar. I also did not address the data or placement that this bar would likely represent in a real-world application. Depending what one is measuring, there is no such single solution to apply to all use cases. Thus, I leave that part of the problem to the reader.
Fast, Bash, and no forks
#!/usr/bin/bash
bar='###################################################################'
for (( i=${#bar}; i>0; i-- )); do
echo -ne "${bar:1:$i}-\r"
sleep .1s
done
After 0.3s
_$ #################################################################'
After 1.8s
_$ ##################################################
After 4.6s
_$ ###################
and so on.
Bar Can be any character or length
bar1='#######'
or
bar2='++++++++++++'
Bash for loop
for (( i=${#bar}; i>0; i-- )); do
Bash parameter expansion gives the length of the string variable
i=${#bar}
Echo with suppress newline flag and interpret escaped chars flag -n -e
echo -ne
Bash Substring Expansion variable $i expands to the number of chars in string: ${bar} on the first iteration and then counts down from there. This could also be done with a negative offset.
${parameter:offset:length}
e.g.
${bar::$i}
Bar can be replaced by other chars or even whitespace; the carriage return "backspaces" the rightmost char, then a single digit and replace some other char or whitespace, e.g. a hyphen '-'
-\r
or
+\r
Configurable timing; sleep takes integers and floats as input, so configuring this to run every half-second or multiple fractions of a second like 2.7 seconds
sleep .1s
© 2022 - 2024 — McMap. All rights reserved.