1

I'm rather new to BASH and I was wondering how could I print 2 strings on the same 2 lines.

What I'm trying to do, is create a 2 line progress-bar in BASH. Creating 1 line progress bar is rather easy, I do it like this:

echo -en 'Progress: ###          - 33%\r'
echo -en 'Progress: #######      - 66%\r'
echo -en 'Progress: ############ - 100%\r'
echo -en '\n'

But now I'm trying to do the same thing but with 2 lines, and everything I tried failed so far.

In the second line, I want to put a "Progress Detail" that tells me at what point in the script it is, like for example: what variable is gathering, what function is it running. But I just can't seem to create a 2 line progress bar.

3
  • Sorry pal, but i don't think you can do that. But why not consider putting the progress in the same line
    – sjsam
    Commented Apr 18, 2017 at 16:53
  • Possible duplicate of How to add a progress bar to a shell script?
    – djm.im
    Commented Apr 18, 2017 at 21:10
  • @djm No, that only covers single-line progress bars. This is specifically asking about multiple lines.
    – tripleee
    Commented Apr 19, 2017 at 4:14

2 Answers 2

1

It's possible to overwrite double lines using tput and printf, for example:

function status() { 
    [[ $i -lt 10 ]] && printf "\rStatus Syncing %0.0f" "$(( i * 5 ))" ; 
    [[ $i -gt 10 ]] && printf "\rStatus Completing %0.0f" "$(( i * 5 ))" ;
    printf "%% \n" ;
}

for i in {1..20}
do status
    printf "%0.s=" $(seq $i) ; 
    sleep .25 ; tput cuu1 ; 
    tput el ; 
done ; printf "0%%\n" ; printf " %.0s" {1..20} ; printf "\rdone.\n"

one-liner:

for i in {1..20}; do status ; printf "%0.s=" $(seq $i) ; sleep .25 ; tput cuu1 ; tput el ; done ; printf "0%%\n" ; printf " %.0s" {1..20} ; printf "\rdone.\n"

The loop calls the status function to display the appropriate text during a particular time.

The resulting output would be similar to:

Status Completing 70%
==============
0

You can use \033[F to go to previous line, and \033[2K to erase the current line (just in case your output length changes).

That's the script I did:

echo -en 'Progress: ###          - 33%\r'
echo -en "\ntest"   # writes progress detail
echo -en "\033[F\r" # go to previous line and set cursor to beginning

echo -en 'Progress: #######      - 66%\r'
echo -en "\n\033[2K" # new line (go to second line) and erase current line (aka the second one)
echo -en "test2"     # writes progress detail
echo -en "\033[F\r"  # go to previous line and set cursor to beginning

echo -en 'Progress: ############ - 100%\r'
echo -en "\n\033[2K" # new line and erase the line (because previous content was "test2", and echoing "test" doesn't erase the "2")
echo -en "test"      # write progress detail
echo -en '\n'

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