Line with changing percents in Terminal


#1

How to make a row in terminal, which change percent status in a same line, not in a new line.
Like when cocoapod updates, it is write:

$ update
update start
podname updating 98% percents already

So 98 percents is changing in the same line.
Is it an option of print() function?
Sorry for stupid question, I hope it is understandingly.


(Kirill Titov) #2

Well, obvious answer should be

import Foundation

print("Hello")

for i in 0...100 {
    usleep(.random(in: 1000...10000))
    print("Current progress is \(i)%", terminator: "\r")
}

print("Done")

But for some reason it just doesn't work as expected, it just prints last one, with 100%, omitting live progress.


(Vincent Duvert) #3

That’s because the standard output is buffered; it’s only sent to the terminal when a \n is encountered. You need to manually flush it (with fflush(stdout)) after sending new data:

import Foundation

print("Hello")

for i in 0...100 {
    usleep(.random(in: 1000...10000))
    print("Current progress is \(i)%", terminator: "\r")
    fflush(stdout)
}

print("\nDone")

I also added a line return before the “Done”, to prevent it from replacing part of the “Current progress” text.


(Kirill Titov) #4

Well, not quite obvious :) print func then should have param flush: Bool = true or smth.


(Happy Human Pointer) #5
func print(_ args: Any..., separator: String = " ", terminator: String = "\n", flush: Bool = false) {
    let string = (args.map { String(describing: $0) }).joined(separator: separator) + terminator
    print(string)
    if flush {
        fflush(stdout)
    }
}

You can if you want