By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,977 Members | 1,369 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,977 IT Pros & Developers. It's quick & easy.

subprocess communication, exec()

P: n/a
If I run 'python -i subprocessclient.py' I expect to see the nice
level of it go up 2, and the nice level of the subprocess go up 1.
But all I see is the nice level of the client change. What am I doing
wrong?

subprocessserver.py:
----------------------------
#!/usr/bin/python2.5

import os
import sys

while True:
next_line = sys.stdin.readline()
if not next_line:
break
exec(next_line)
# sys.stdout.write(output)
# sys.stdout.write(next_line)
# sys.stdout.flush()
----------------------------

subprocessclient.py:
----------------------------
#!/usr/bin/python2.5

import subprocess, os

server = subprocess.Popen(('python2.5', 'subprocessserver.py'),
shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)

os.nice(2)

server.stdin.write('''os.nice(1)''')
----------------------------

Thanks.
-Chuckk

--
http://www.badmuthahubbard.com
Nov 11 '08 #1
Share this Question
Share on Google+
2 Replies


P: n/a
On Nov 11, 1:23 pm, "Chuckk Hubbard" <badmuthahubb...@gmail.com>
wrote:
If I run 'python -i subprocessclient.py' I expect to see the nice
level of it go up 2, and the nice level of the subprocess go up 1.
But all I see is the nice level of the client change. What am I doing
wrong?

subprocessserver.py:
----------------------------
#!/usr/bin/python2.5

import os
import sys

while True:
next_line = sys.stdin.readline()
if not next_line:
break
exec(next_line)
# sys.stdout.write(output)
# sys.stdout.write(next_line)
# sys.stdout.flush()
----------------------------

subprocessclient.py:
----------------------------
#!/usr/bin/python2.5

import subprocess, os

server = subprocess.Popen(('python2.5', 'subprocessserver.py'),
shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)

os.nice(2)

server.stdin.write('''os.nice(1)''')
----------------------------

Thanks.
-Chuckk

--http://www.badmuthahubbard.com
Looks like you're dropping an error by redirecting the child process'
standard error into a pipe.

First off, remove the stderr=subprocess.PIPE from
subprocessclient.py. When you do so, you'll start seeing an error
message whenever your code runs:

[jeff@marvin ~]$ python client.py
None
[jeff@marvin ~]$ Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined

That doesn't make a lot of sense at first, until you consider the
following:

[jeff@marvin ~]$ echo 'os.nice(1)' | python
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined

The Python interpreter is trying to execute the data you write to the
stdin of the child process. Changing the Popen line to use the string
form rather than the sequence form remedies the problem, as does
changing 'string=True' to 'string=False.'

The reason? Because when you set shell=True, additional arguments in
args sequence are passed as additional arguments to the shell itself,
not to the command.

From subprocess.py:

if isinstance(args, types.StringTypes):
args = [args]
else:
args = list(args)

if shell:
args = ["/bin/sh", "-c"] + args

So, in your attempt, you're effectively doing the following:

/bin/sh -c "python2.5" "server.py"

When you want:

/bin/sh -c "python2.5 server.py"

HTH,

Jeff
Nov 11 '08 #2

P: n/a
On Tue, Nov 11, 2008 at 9:39 PM, Jeff McNeil <je**@jmcneil.netwrote:
On Nov 11, 1:23 pm, "Chuckk Hubbard" <badmuthahubb...@gmail.com>
wrote:
>If I run 'python -i subprocessclient.py' I expect to see the nice
level of it go up 2, and the nice level of the subprocess go up 1.
But all I see is the nice level of the client change. What am I doing
wrong?

subprocessserver.py:
----------------------------
#!/usr/bin/python2.5

import os
import sys

while True:
next_line = sys.stdin.readline()
if not next_line:
break
exec(next_line)
# sys.stdout.write(output)
# sys.stdout.write(next_line)
# sys.stdout.flush()
----------------------------

subprocessclient.py:
----------------------------
#!/usr/bin/python2.5

import subprocess, os

server = subprocess.Popen(('python2.5', 'subprocessserver.py'),
shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)

os.nice(2)

server.stdin.write('''os.nice(1)''')
----------------------------

Thanks.
-Chuckk

--http://www.badmuthahubbard.com

Looks like you're dropping an error by redirecting the child process'
standard error into a pipe.

First off, remove the stderr=subprocess.PIPE from
subprocessclient.py. When you do so, you'll start seeing an error
message whenever your code runs:

[jeff@marvin ~]$ python client.py
None
[jeff@marvin ~]$ Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined

That doesn't make a lot of sense at first, until you consider the
following:

[jeff@marvin ~]$ echo 'os.nice(1)' | python
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined

The Python interpreter is trying to execute the data you write to the
stdin of the child process. Changing the Popen line to use the string
form rather than the sequence form remedies the problem, as does
changing 'string=True' to 'string=False.'

The reason? Because when you set shell=True, additional arguments in
args sequence are passed as additional arguments to the shell itself,
not to the command.
From subprocess.py:

if isinstance(args, types.StringTypes):
args = [args]
else:
args = list(args)

if shell:
args = ["/bin/sh", "-c"] + args

So, in your attempt, you're effectively doing the following:

/bin/sh -c "python2.5" "server.py"

When you want:

/bin/sh -c "python2.5 server.py"

HTH,

Jeff
That helps immensely, Jeff, thank you for explaining all that. I took
out 'shell=True' and it works, and I took out the stdout and stderr
arguments to debug. I am finally able to perform every step in my
plan: start a child process of python running a script that imports
the Csound API; raise the nice level of the parent process; compile
and run a Csound orchestra remotely; and send it notes from the parent
process.
Thanks for your help.
-Chuckk

--
http://www.badmuthahubbard.com
Nov 11 '08 #3

This discussion thread is closed

Replies have been disabled for this discussion.