Console progress bar for Golang

Overview

Terminal progress bar for Go

Coverage Status

Installation

go get github.com/cheggaaa/pb/v3

Documentation for v1 bar available here

Quick start

package main

import (
	"time"
	
	"github.com/cheggaaa/pb/v3"
)

func main() {
	count := 100000
	// create and start new bar
	bar := pb.StartNew(count)
	
	// start bar from 'default' template
	// bar := pb.Default.Start(count)
	
	// start bar from 'simple' template
	// bar := pb.Simple.Start(count)
	
	// start bar from 'full' template
	// bar := pb.Full.Start(count)
	
	for i := 0; i < count; i++ {
		bar.Increment()
		time.Sleep(time.Millisecond)
	}
	bar.Finish()
}

Result will be like this:

> go run test.go
37158 / 100000 [================>_______________________________] 37.16% 1m11s

Settings

// create bar
bar := pb.New(count)

// refresh info every second (default 200ms)
bar.SetRefreshRate(time.Second)

// force set io.Writer, by default it's os.Stderr
bar.SetWriter(os.Stdout)

// bar will format numbers as bytes (B, KiB, MiB, etc)
bar.Set(pb.Bytes, true)

// bar use SI bytes prefix names (B, kB) instead of IEC (B, KiB)
bar.Set(pb.SIBytesPrefix, true)

// set custom bar template
bar.SetTemplateString(myTemplate)

// check for error after template set
if err = bar.Err(); err != nil {
    return
}

// start bar
bar.Start()

Progress bar for IO Operations

package main

import (
	"crypto/rand"
	"io"
	"io/ioutil"

	"github.com/cheggaaa/pb/v3"
)

func main() {

	var limit int64 = 1024 * 1024 * 500
	// we will copy 200 Mb from /dev/rand to /dev/null
	reader := io.LimitReader(rand.Reader, limit)
	writer := ioutil.Discard

	// start new bar
	bar := pb.Full.Start64(limit)
	// create proxy reader
	barReader := bar.NewProxyReader(reader)
	// copy from proxy reader
	io.Copy(writer, barReader)
	// finish bar
	bar.Finish()
}

Custom Progress Bar templates

Rendering based on builtin text/template package. You can use existing pb's elements or create you own.

All available elements are described in element.go file.

All in one example:

tmpl := `{{ red "With funcs:" }} {{ bar . "<" "-" (cycle . "↖" "↗" "↘" "↙" ) "." ">"}} {{speed . | rndcolor }} {{percent .}} {{string . "my_green_string" | green}} {{string . "my_blue_string" | blue}}`
// start bar based on our template
bar := pb.ProgressBarTemplate(tmpl).Start64(limit)
// set values for string elements
bar.Set("my_green_string", "green").
	Set("my_blue_string", "blue")
Comments
  • How to implement Multiple Progress Bars???

    How to implement Multiple Progress Bars???

    Problem

    Hi there,

    I have a list of files being downloaded by different go routines...

            for i := 0; i < len(urls); i++ {
                    go func() { c <- download(urls[i])() }()
            }
    

    I added the pb() implementation and it shows the progress bar, but it only displays in the same line...

    Feature Request

    • Is there a way to control which line the progress bar will be printed?
    • If this is possible, I'd like to suggest the method "SetIndex" to set which line the progress must be printed after the current position on the terminal...
    • Any suggestions to change the Format method to do that?
    // Sets the index of the progress, which gives the line position after the current terminal position.
    func (pb *ProgressBar) SetIndex(index int) {}
    

    This is similar to Docker's progress bars while pulling images...

    [boot-1.pkg] 3.66 MB / 128.94 MB [==>------------------------------------------------] 2.84 % 759.61 KB/s 2m48s
    [boot-2.pkg] 23.66 MB / 48.94 MB [===================>-------------------] 45.84 % 629.61 KB/s 2m48s
    [boot-3.pkg] 30.00 MB / 300.94 MB [=====>------------------------------------------] 10.84 % 459.61 KB/s 2m48s
    

    thanks! Marcello

    opened by marcellodesales 20
  • Implement io.ReadWriteCloser for the Proxy

    Implement io.ReadWriteCloser for the Proxy

    This is helpful when passing the proxy to things that will call close when the proxy conforms to io.Closer, eg https://golang.org/pkg/net/http/#NewRequest:

    "If the provided body is also an io.Closer, the returned Request.Body is set to body and will be closed by the Client methods Do, Post, and PostForm, and Transport.RoundTrip."

    opened by wjessop 11
  • Add parameter to specify elapsed time precision

    Add parameter to specify elapsed time precision

    db60ccefe5cb616c2f8a1bde35ee059118dce62a (released in v3.0.7) increased the resolution shown on elapsed time from seconds to milliseconds. The behavior prior to v3.0.7 was to truncate the time to the nearest second. This patch allows the user to control the precision. The default is to round to the nearest second, like the pre-v3.0.7 behavior. This patch also switches from truncation to rounding.

    This is an alternative to #180, as suggested in https://github.com/cheggaaa/pb/pull/180#issuecomment-813383854.

    opened by anishathalye 9
  • Have ProgressBar implement Read instead of Reader

    Have ProgressBar implement Read instead of Reader

    It might be more natural for ProgressBar to accept a reader (either as an exported member variable or as an unexported member variable and an exported setter), and then implement Read itself instead of having the separate Reader type.

    opened by joshlf 7
  • exponentially weighted moving average would provide more accurate

    exponentially weighted moving average would provide more accurate "time left"

    Instead of using the global average time per entry to calculate the remaining time, using EWMA would give more weight to recent times per entry and would likely provide a more accurate estimate.

    opened by dgryski 7
  • Reduce resolution for elapsed time > 1s

    Reduce resolution for elapsed time > 1s

    #177 increased the resolution shown on elapsed time from seconds to milliseconds. This applied regardless of the total duration, so even if the duration was large, a high resolution would be displayed, such as "897.213s". This patch changes the behavior so that milliseconds are only shown if the total time is less than a second, so that example would be displayed as "897s" instead.

    opened by anishathalye 6
  • Allow for initialising a pool without starting it

    Allow for initialising a pool without starting it

    Maybe fixes #123

    It's not perfect however: https://youtu.be/Oo_L_MHvEmo. In the video pb.go is:

    package main
    
    import (
    	"math/rand"
    	"os"
    	"sync"
    	"time"
    
    	"github.com/wjessop/pb"
    )
    
    func main() {
    	// create bars
    	first := pb.New64(1000).Prefix("one ").SetUnits(pb.U_BYTES)
    	second := pb.New64(1000).Prefix("two ").SetUnits(pb.U_BYTES)
    
    	first.Output = os.Stderr
    	second.Output = os.Stderr
    
    	// start pool
    	// pool, err := pb.StartPool(first, second)
    	pool := pb.NewPool()
    	pool.Output = os.Stderr
    	err := pool.Start()
    	if err != nil {
    		panic(err)
    	}
    
    	// update bars
    	wg := new(sync.WaitGroup)
    	for _, bar := range []*pb.ProgressBar{first, second} {
    		wg.Add(1)
    		go func(cb *pb.ProgressBar) {
    			for n := 0; n < 200; n++ {
    				// cb.Increment()
    				time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
    				cb.Add(5)
    			}
    			cb.Finish()
    			wg.Done()
    		}(bar)
    	}
    	wg.Wait()
    	// close pool
    	pool.Stop()
    }
    
    opened by wjessop 6
  • fix importing with go mod

    fix importing with go mod

    The repositories github.com/mattn/go-colorable and github.com/mattn/go-isatty have moved to using go modules; using gopkg.in to import them breaks:

    https://github.com/golang/go/issues/30636

    Let's use the real URLs with hashes.

    Signed-off-by: Tycho Andersen [email protected]

    opened by tych0 5
  • Rolling pool of bars

    Rolling pool of bars

    I want to use pb to keep progress bars for an updating set of concurrent uploads, where as one upload finishes another takes its place. Is there a good way to do this? I can't see a way to remove a bar from a Pool - or should I just keep adding to the list?

    I'm also interested in usage patterns for progress bar pools. I can either create a pool and gradually add bars as I make them (StartPool() with an empty list followed by multiple Add() calls), or I can collect a group of bars and add them in bulk (StartPool() with a full list). Which do you recommend? I found that if I used the first and there was some lag before I added my first bar, the cursor moved up a line and started eating the previous text in my terminal.

    I've realised this might be two issues - let me know if you want me to separate them or provide some example code.

    opened by psaffrey-illumina 5
  • len out of range issue

    len out of range issue

    Hi,

    when passing a file size of 15762329 (return of fi.Size()) to:

    bar = pb.New64(fi.Size()).SetUnits(pb.U_BYTES).SetRefreshRate(time.Millisecond * 10)
    

    I get the following panic:

    panic: runtime error: makeslice: len out of range
    
    goroutine 15727 [running]:
    panic(0x6ee280, 0xc420400250)
    	/usr/local/go/src/runtime/panic.go:500 +0x1a1
    strings.Repeat(0x74b1d0, 0x1, 0xfffffffffffffffd, 0x7, 0xc4203b00a0)
    	/usr/local/go/src/strings/strings.go:420 +0x49
    github.com/cheggaaa/pb.(*ProgressBar).write(0xc4200ae000, 0x0)
    	/home/hasan/gocode/src/github.com/cheggaaa/pb/pb.go:368 +0xa6c
    github.com/cheggaaa/pb.(*ProgressBar).Update(0xc4200ae000)
    	/home/hasan/gocode/src/github.com/cheggaaa/pb/pb.go:410 +0x5d
    github.com/cheggaaa/pb.(*ProgressBar).Start(0xc4200ae000, 0x74db1e)
    	/home/hasan/gocode/src/github.com/cheggaaa/pb/pb.go:122 +0x95
    ...datastores.(*HTTPDataStore).Write.func1(0xc420100050, 0xc420366380, 0xc42011c040, 0xc4203cc390, 0xc4200ae000, 0xc42011c050, 0xc420400090, 0xc4203062a0)
    	/home/hasan/gocode/src/:127 +0x1a5
    created by ...datastores.(*HTTPDataStore).Write
    	/home/hasan/gocode/src/...rest-http.go:134 +0x4e8
    make: *** [test] Error 2
    
    opened by omani 5
  • DATA RACE

    DATA RACE

    I've a program where bar.Increment() is in goroutine.

    I've check program with -race

    WARNING: DATA RACE Read by goroutine 7: github.com/cheggaaa/pb.(_ProgressBar).GetWidth() /home/julien/go/src/github.com/cheggaaa/pb/pb.go:327 +0x37 github.com/cheggaaa/pb.(_ProgressBar).write() /home/julien/go/src/github.com/cheggaaa/pb/pb.go:227 +0x72 github.com/cheggaaa/pb.(_ProgressBar).Update() /home/julien/go/src/github.com/cheggaaa/pb/pb.go:344 +0x7d github.com/cheggaaa/pb.(_ProgressBar).writer() /home/julien/go/src/github.com/cheggaaa/pb/pb.go:351 +0x40 Goroutine 7 (running) created at: github.com/cheggaaa/pb.(*ProgressBar).Start() /home/julien/go/src/github.com/cheggaaa/pb/pb.go:105 +0x150 github.com/cheggaaa/pb.StartNew() /home/julien/go/src/github.com/cheggaaa/pb/pb.go:53 +0x3c main.main()

    How can I correct this ?

    opened by jhautefeuille 5
  • Incorrect values of downloaded and percentage

    Incorrect values of downloaded and percentage

    Downloading a large file, result incorrect output of megabytes of downloaded size and current percentage of download. File that I download: https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-11.3.0-amd64-netinst.iso image

    Total size of the file in ContentLength is nearly 378 MiB however pb shows that it only downloaded 376.79 MiB where it downloaded 378 MiB and same goes with the percentage, it's didn't reach 100% where it should be.

    opened by rilysh 1
  • [Question]: How to use more colors?

    [Question]: How to use more colors?

    Some colors are defined in defaultTemplateFuncs, but these are only some of the colors in the color package, how to use more colors quickly?

    // Foreground text colors
    const (
    	FgBlack Attribute = iota + 30
    	FgRed
    	FgGreen
    	FgYellow
    	FgBlue
    	FgMagenta
    	FgCyan
    	FgWhite
    )
    
    // Foreground Hi-Intensity text colors
    const (
    	FgHiBlack Attribute = iota + 90
    	FgHiRed
    	FgHiGreen
    	FgHiYellow
    	FgHiBlue
    	FgHiMagenta
    	FgHiCyan
    	FgHiWhite
    )
    
    opened by thep0y 0
  • feature req: ProxyReadSeeker

    feature req: ProxyReadSeeker

    I'm in need of a ProxyReadSeeker to wrap ReadSeekers (like files) for use with the AWS go SDK. stuff like s3.PutObject() says it takes an io.Reader, but really requires an io.ReadSeeker since it reads the data once to calculate checksums and then again to send it to S3.

    I'm envisioning that the progress bar goes backwards when it seeks back, and then moves forwards again, basically tracking the current read position as it goes. Hopefully shouldn't be too hard to implement. I'm willing to take a stab at it, if you agree to the general design.

    opened by nergdron 2
  • Progress bars rendering is disturbed when terminal screen size is small

    Progress bars rendering is disturbed when terminal screen size is small

    @cheggaaa

    When the terminal screensize is small and the number of progress bars are more the progress bars rendering fails

    func Example_multiple() {
    	// create bars
    	//first := pb.New(200).Prefix("App1 Deployment Status := Pending")
    	//second := pb.New(200).Prefix("App1 Deployment Status := Pending ")
    	//third := pb.New(200).Prefix("App1 Deployment Status := Pending ")
    	numberOfBars := 100
    	var pbs []*pb.ProgressBar
    	for i:=1 ;i<=numberOfBars ; i++ {
    		bar := pb.New(100).Prefix(fmt.Sprintf("App%d Deployment Status := Pending",i))
    		pbs = append(pbs,bar)
    	}
    
    	// start pool
    	//pool, err := pb.StartPool(first, second, third)
    	pool, err := pb.StartPool(pbs...)
    	if err != nil {
    		panic(err)
    	}
    	// update bars
    	wg := new(sync.WaitGroup)
    	for i:=0 ;i<numberOfBars ; i++ {
    		wg.Add(1)
    		go func(cb *pb.ProgressBar,appName string) {
    			for n := 0; n < int(cb.Total); n++ {
    				cb.Increment()
    				time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
    				cb.Prefix(fmt.Sprintf("%s Deployment Status := Inprogress",appName))
    			}
    			cb.Finish()
    			wg.Done()
    		}(pbs[i],fmt.Sprintf("App%d",i+1))
    	}
    	wg.Wait()
    	// close pool
    	pool.Stop()
    }
    
    Screenshot 2020-11-07 at 22 23 42
    opened by harshit22394 0
  • How to add break line to Prefix

    How to add break line to Prefix

    I want to add the break line between prefix and the progress bar [1/3]Prefix [2/3]#####################################################--------------------------------------------------------------------------------------------21/58

    to be like this:

    [1/3]Prefix 
    [2/3]#####################################################--------------------------------------------------------------------------------------------21/58
    

    my code:

    bar.Prefix(fmt.Sprintf("[1/3] Prefix)) // add \n after this won't work
    bar.Increment()
    bar.BarEnd = fmt.Sprintf(
     "%v/%v",
     bar.Get(),
     len(total),
                      )
    

    Many thanks!!

    opened by minhkhiemm 0
Owner
Sergey Cherepanov
Sergey Cherepanov
progress_bar creates a single customizable progress bar for Linux terminal.

progress_bar Go Progress Bar Features progress_bar creates a single customizable progress bar for Linux terminal. Installation go get -u github.com/er

erman imer 127 Aug 12, 2022
multi progress bar for Go cli applications

Multi Progress Bar mpb is a Go lib for rendering progress bars in terminal applications. Features Multiple Bars: Multiple progress bars are supported

Vladimir Bauer 1.9k Nov 23, 2022
Go simple progress bar writing to output

?? progress-go Go simple progress bar writing to output ?? ABOUT Contributors: Rafał Lorenz Want to contribute ? Feel free to send pull requests! Have

Rafał Lorenz 53 Oct 30, 2022
Utilities to prettify console output of tables, lists, progress-bars, text, etc.

go-pretty Utilities to prettify console output of tables, lists, progress-bars, text, etc. Table Pretty-print tables into ASCII/Unicode strings.

Naveen Mahalingam 1.6k Nov 27, 2022
🍫 A customisable, universally compatible terminal status bar

Shox: Terminal Status Bar A customisable terminal status bar with universal shell/terminal compatibility. Currently works on Mac/Linux. Installation N

Liam Galvin 680 Nov 21, 2022
A cli that shows a GitHub-like language usage statistics bar.

barley A cli that shows a GitHub-like language usage statistics bar. barley analyses the programming languages used in a directory and creates a used

Barış İnandıoğlu 3 Jan 8, 2022
Custom i3status bar built with Barista.

Custom i3status Customized i3status command built with Barista. Includes a Barista module for strongSwan. Install go install enr0n.net/i3status/cmd/i3

Nick Rosbrook 1 Jan 10, 2022
Go (golang) package with 70+ configurable terminal spinner/progress indicators.

Spinner spinner is a simple package to add a spinner / progress indicator to any terminal application. Examples can be found below as well as full exa

Brian Downs 1.9k Nov 15, 2022
Golang-video-screensaver - A work in progress Microsoft Windows video screensaver implemented in Go

golang-video-screensaver A work in progress Microsoft Windows video screensaver

null 1 Sep 5, 2022
hierarchical progress bars in terminal on steroids

Echelon - hierarchical progress in terminals Cross-platform library to organize logs in a hierarchical structure. Here is an example how it looks for

Cirrus Labs 346 Nov 26, 2022
Print day progress in your terminal

Day progress Print day progress in your terminal Install go install github.com/tsivinsky/[email protected] Usage day-progress By default, day-progre

Daniil Tsivinsky 0 Jan 10, 2022
Use Golang to achieve better console backend services

Use Golang to achieve better console backend services

null 1 Dec 7, 2021
Windows API to hide console window by golang

Doge-Hide windows API to hide console window by golang ShowWindow ShowWindowAsy

TimWhite 14 Nov 7, 2022
Console-based JVM monitoring tool

jvm-mon Console based JVM monitoring - when you just want to SSH into a server and see what's going on. jvm-top lets you monitor your JVM server appli

Andrejs Jermakovics 1.4k Nov 17, 2022
Disk usage analyzer with console interface written in Go

Gdu is intended primarily for SSD disks where it can fully utilize parallel processing. However HDDs work as well, but the performance gain is not so huge.

Daniel Milde 2.1k Nov 23, 2022
Integrated console application library, using Go structs as commands, with menus, completions, hints, history, Vim mode, $EDITOR usage, and more ...

Gonsole - Integrated Console Application library This package rests on a readline console library, (giving advanced completion, hint, input and histor

null 18 Nov 20, 2022
oc CLI plugin to interact with Helm features provided by the OpenShift Console

OpenShift provides support for managing the lifecycle of Helm charts. This capability is limited primarily to the Web Console. This plugin enables the management of Helm charts similar to using the standalone Helm CLI while offloading much of the work to OpenShift.

Andrew Block 0 Aug 20, 2022
Simple console formatting library for Go

flair Simple console formatting library for Go Motivation There are definitely a bunch of other libraries like this, but I wanted one I knew would be

Beatrice T. Meyers 3 Aug 30, 2021
This is a Go Cli app that receives an string path to a log file, and based on it generates and prints in console an encoded polyline with the locations found in the log file.

GEOENCODE GO CLI APP DESCRIPTION This is a Go Cli app that receives an string path to a log file, and based on it generates and prints in console an e

Jose Luis Ojeda 1 Oct 1, 2021