Subprocess and /usr/bin/dialog


H

harrelson

I am trying to get the below code to work and can't quite make things
happen. This is with Python 2.5.1. Dialog is doing something odd...
I have tinkered with different combinations and I can't get the dialog
to show properly-- it does show properly directly in the shell. Any
hints?

import subprocess
command = '/usr/bin/dialog --clear --title "title" --menu "text" 20 50
5 "a" "this and that" "c" "3 this and that" "b" "2 this and that" "d"
"4 this and that"'
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
#proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
stderr_value = proc.communicate()[0]
print stderr_value
 
Ad

Advertisements

G

Grant Edwards

I am trying to get the below code to work and can't quite make things
happen. This is with Python 2.5.1. Dialog is doing something odd...
I have tinkered with different combinations and I can't get the dialog
to show properly-- it does show properly directly in the shell. Any
hints?

import subprocess
command = '/usr/bin/dialog --clear --title "title" --menu "text" 20 50
5 "a" "this and that" "c" "3 this and that" "b" "2 this and that" "d"
"4 this and that"'
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
#proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
stderr_value = proc.communicate()[0]
print stderr_value

[It would be helpful if you didn't wrap sample code when you
post it.]

dialog displays the widget on stdout. You've connected stdout
to a pipe, so you're not going to see anything displayed unless
you read data from the stdout pipe and write it to the terminal.
 
H

harrelson

I am trying to get the below code to work and can't quite make things
happen. This is with Python 2.5.1. Dialog is doing something odd...
I have tinkered with different combinations and I can't get the dialog
to show properly-- it does show properly directly in the shell. Any
hints?
import subprocess
command = '/usr/bin/dialog --clear --title "title" --menu "text" 20 50
5 "a" "this and that" "c" "3 this and that" "b" "2 this and that" "d"
"4 this and that"'
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
#proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
stderr_value = proc.communicate()[0]
print stderr_value

[It would be helpful if you didn't wrap sample code when you
post it.]

Sorry I posted through google groups and it wrapped it for me...
dialog displays the widget on stdout. You've connected stdout
to a pipe, so you're not going to see anything displayed unless
you read data from the stdout pipe and write it to the terminal.

Reading this tutorial on subprocess:

http://blog.doughellmann.com/2007/07/pymotw-subprocess.html

led me to believe this was exactly what I was doing. The screen does
actually turn blue for a second but it is as if I only get one
keystroke and python is back in control...
 
H

harrelson

[It would be helpful if you didn't wrap sample code when you
post it.]

dialog displays the widget on stdout. You've connected stdout
to a pipe, so you're not going to see anything displayed unless
you read data from the stdout pipe and write it to the terminal.

Also... if I put the dialog call in a one line shell script and
execute it with:

subprocess.call('dialog.sh')

it works properly.
 
G

Grant Edwards

proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stderr_value = proc.communicate()[0]
print stderr_value
dialog displays the widget on stdout. You've connected stdout
to a pipe, so you're not going to see anything displayed unless
you read data from the stdout pipe and write it to the terminal.

Reading this tutorial on subprocess:

http://blog.doughellmann.com/2007/07/pymotw-subprocess.html

led me to believe this was exactly what I was doing.

Ah, my mistake. I believed you when you named the variable
"stderr_value". ;)

I've never used the communicate() method, but according to that
tutorial:

"The communicate() method reads all of the output and waits for
child process to exit before returning.

And the lib references says:

communicate(input=None)

Interact with process: Send data to stdin. Read data from
stdout and stderr, until end-of-file is reached. Wait for
process to terminate. The optional input argument should be
a string to be sent to the child process, or None, if no
data should be sent to the child.

communicate() returns a tuple (stdout, stderr).

The key is that it doesn't return until after the subprocess
has terminated.

So, you're reading stdout and putting it in the variable you
named stderr_value. After the dialog exits, you then print the
stdout string (which contains the widget's "display" data).
Since the widget has already exited, that string contains both
the initial display _and_ the escape sequence that clears the
screen and restores it. So, you just see a flash of blue. If
you want to be able to see and interact with the widget, you
need to leave stdout connected to the terminal while the widget
is running.

Try this:

------------------------------------------------------------
import subprocess
command = '/usr/bin/dialog --clear --title "title" --menu "text" 20 50 5 "a" "this and that" "c" "3 this and that" "b" "2 this and that" "d" "4 this and that"'
proc = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE)
stdout,stderr = proc.communicate()
print stderr
------------------------------------------------------------

NB: using shell=True introduces a number security holes and
adds the overhead of starting a shell. It's good practice
to avoid it if you don't actually need a shell (you don't).
However, without it you need to split up the command line
explicitly:

------------------------------------------------------------
import subprocess
command = ('/usr/bin/dialog','--clear','--title','title', '--menu','text','20','50','5',
'a','this and that',
'c','3 this and that',
'b','2 this and that',
'd','4 this and that')
proc = subprocess.Popen(command, stderr=subprocess.PIPE)
stdout,stderr = proc.communicate()
print stderr
 
Ad

Advertisements

H

harrelson

Thanks Grant, that does it! I knew it had to be something simple like
that and it was frustrating not to be able to find it. I do prefer
the tuple. Thanks again.

culley
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top