Updating Whiptail gauge (Progress bar) with Python

I spent last week writing a Python script to create an installer for some services, and I wanted to show the installation progress using a gauge. So I used the whiptail utility which comes with most linux distros as it was easier to use for this particular task. However, there was one caveat, that it reads the progress value from the standard input. It was a bit tricky and took me bit of a time to figure it out...but this is how to do it.

It's mentioned in the manual.

--gauge text height width percent
              A gauge box displays a meter along the bottom of the box.  The meter indicates a percentage.  New percentages are read from standard input, one
              integer  per  line.  The meter is updated to reflect each new percentage.  If stdin is XXX, the first following line is a percentage and subse‐
              quent lines up to another XXX are used for a new prompt.  The gauge exits when EOF is reached on stdin.

Whiptail is a bash utility so we have to call the bash command within our python script. I used subprocess module to do that. Since we have to input the progress values to the command using the standard input, we have to set it's stdin to subprocess.PIPE. Whiptail will print to the stdout, so we don't really have anything to do there (means, it will read from the stdin and display the progress accordingly.)

#!/usr/bin/env python

import subprocess
import time

process = subprocess.Popen(["whiptail", "--title", "Progress", "--gauge", "", "6", "50", "0"], stdin=subprocess.PIPE)

for i in range(0,101, 10):
    time.sleep(1)
    process.stdin.write(b'{}\n'.format(i))
    process.stdin.flush()


So this is it. If you run this script, you will see the progress bar updates and reflects the new progress nicely.


Updating Whiptail gauge (Progress bar) with Python


One thing to note here is that you may have seen in many places that they don't recommend to use stdin.write directly due to deadlocks etc, and ask to use communicate(input="") method. But it's not definitely going to work here as the communicate(input="") method is going to write to the stdin and waits for the process to exit. That way we won't be able to keep updating the progress bar. That was from my understanding, but I might be wrong. If you know any better way to do this, or to use communicate(input="") instead of stdin.write(), feel free to leave a comment and let me know.


3 comments :

  1. Hi, I’m Theodore Ginsburg and I live in Singapore. I’m here to share my own view to the world about how I was helped by Lord Zakuza with his powerful spells for bringing back my boyfriend who neglected and broke up with me for the past 2 and half years. I can’t say much because I really don’t know how to express myself right now for I’m overwhelmed but I really want to appreciate and thank Lord Zakuza for his honesty and gracious work in my life. Thank you xoxo much. Anyone reading this that needs his service can get in touch with him through his WhatsApp number on +17405739483 or via Email on: doctorzakuzaspelltemple@hotmail.com

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete