Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simultaneous progress bars

Tags:

terminal

ruby

This script creates a pseudo progress bar:

bar, bar2 = '', ''
10.times do |i|
  bar << '='
  bar2 << '**'
  print "#{bar} - #{i+1}0%\r"
  #print "#{bar2} - #{i+1}0%\r"
  sleep 0.3
end

10 = appear in the bottom left of the screen before it completes.

I want to create two simultaneous loading bars. So as you can see, I've created bar2 that creates 20 * before it completes.

Both work fine, but not simultaneously! If I uncomment both print commands, I print both bars, only the bar2 is shown, bar1 doesn't show up at all.

I'm guessing this is because the \r returns the "cursor" to the start of the line and overrides bar with bar2's progress.

I've tried utilizing a \n, but all text preceding the \n is not wiped. Again, this is because \r is carriage return that can't get before a new line, so while the first loop actually works perfectly, bar's progress (and a \n) stays on the screen, causing this effect:

> = - 10%
> == - 20%
> === - 30%%
> ==== - 40%0%
> ===== - 50%40%
> ====== - 60% 50%
> ======= - 70%- 60%
> ======== - 80% - 70%
> ========= - 90%* - 80%
> ========== - 100%* - 90%

So how do I create two simultaneous loading bars? Or indeed an infinite number of simultaneous loading bars? I'm testing in gnome-terminal but I'd like a solution that works in most, if not all, modern terminals.

like image 273
JayTarka Avatar asked Mar 12 '26 04:03

JayTarka


1 Answers

This is a pretty cool little problem. Basically, you got it right that you can overwrite the current line with \r. Now you just need a character, which can jump back to the previous line. You can use "\033[F" for that:

bar, bar2 = '', ''
10.times do |i|
  bar << '='
  bar2 << '**'
  puts  "#{bar} - #{i+1}0%"
  print "#{bar2} - #{i+1}0%"
  print "\033[F\r"
  sleep 0.3
end
like image 185
ndnenkov Avatar answered Mar 14 '26 10:03

ndnenkov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!