G.A.
G.A.

Reputation: 1523

Feed python output to whiptail

I would like to use a TUI (text user interface) on a headless linux server by passing output of some PYTHON code to 'whiptail'. Unfortunately, nothing seems to happen in whiptail. When I pipe the output from a regular shell script, then whiptail works fine. Here is what I have:

data-gen.sh

#!/bin/bash
echo 10
sleep 1
echo 20
sleep 1
...
...
echo 100
sleep 1

$ ./data-gen.sh | whiptail --title "TEST" --gauge "GAUGE" 0 50 0

I get the below progress bar incrementing as expected.

Whiptail working when piping output from shell script


Now I try to replicate same thing from python:

data-gen.py

#!/usr/bin/python
import time

print 10
time.sleep(1)
...
...
print 100
time.sleep(1)

$ ./data-gen.py | whiptail --title "TEST" --gauge "GAUGE" 0 50 0

I get the below progress bar staying at 0%. No increment seen. Whiptail does exit once the python program in the background has exited.

No change in progress bar when piping python output

Any ideas how to get python output to be piped successfully to whiptail ? I have not tried this with dialog; since I wanted to stick to whiptail which is pre-installed on most ubuntu distros.

Upvotes: 1

Views: 1734

Answers (1)

Arkadiusz Drabczyk
Arkadiusz Drabczyk

Reputation: 12393

man whiptail says:

--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 subsequent lines up to another XXX are used for a
          new prompt.  The gauge exits when EOF is reached on
          stdin.

That means that whiptail reads from standard input. Many programs commonly buffer output when it's not going to the file. To force python to produce unbuffered output you can either:

  • Run it with unbuffer:

    $ unbuffer ./data-gen.py | whiptail --title "TEST" --gauge "GAUGE" 0 50 0
    
  • Use -u switch on the command line:

    $ python -u ./data-gen.py | whiptail --title "TEST" --gauge "GAUGE" 0 50 0
    
  • Modify the shebang of data-gen.py:

    #!/usr/bin/python -u
    import time
    print 10
    time.sleep(1)
    print 20
    time.sleep(1)
    print 100
    time.sleep(1)
    
  • Manually flush stdout after each print:

    #!/usr/bin/python
    import time
    import sys
    
    print 10
    sys.stdout.flush()
    time.sleep(1)
    print 20
    sys.stdout.flush()
    time.sleep(1)
    print 100
    sys.stdout.flush()
    time.sleep(1)
    
  • Set PYTHONUNBUFFERED environment variable:

    $ PYTHONUNBUFFERED=1 ./data-gen.py | whiptail --title "TEST" --gauge "GAUGE" 0 50 0
    

Upvotes: 1

Related Questions