subprocess communication, exec()

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Chuckk Hubbard

    subprocess communication, exec()

    If I run 'python -i subprocessclien t.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?

    subprocessserve r.py:
    ----------------------------
    #!/usr/bin/python2.5

    import os
    import sys

    while True:
    next_line = sys.stdin.readl ine()
    if not next_line:
    break
    exec(next_line)
    # sys.stdout.writ e(output)
    # sys.stdout.writ e(next_line)
    # sys.stdout.flus h()
    ----------------------------

    subprocessclien t.py:
    ----------------------------
    #!/usr/bin/python2.5

    import subprocess, os

    server = subprocess.Pope n(('python2.5', 'subprocessserv er.py'),
    shell=True, stdin=subproces s.PIPE, stdout=subproce ss.PIPE,
    stderr=subproce ss.PIPE)

    os.nice(2)

    server.stdin.wr ite('''os.nice( 1)''')
    ----------------------------

    Thanks.
    -Chuckk

    --

  • Jeff McNeil

    #2
    Re: subprocess communication, exec()

    On Nov 11, 1:23 pm, "Chuckk Hubbard" <badmuthahubb.. .@gmail.com>
    wrote:
    If I run 'python -i subprocessclien t.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?
    >
    subprocessserve r.py:
    ----------------------------
    #!/usr/bin/python2.5
    >
    import os
    import sys
    >
    while True:
    next_line = sys.stdin.readl ine()
    if not next_line:
    break
    exec(next_line)
    # sys.stdout.writ e(output)
    # sys.stdout.writ e(next_line)
    # sys.stdout.flus h()
    ----------------------------
    >
    subprocessclien t.py:
    ----------------------------
    #!/usr/bin/python2.5
    >
    import subprocess, os
    >
    server = subprocess.Pope n(('python2.5', 'subprocessserv er.py'),
    shell=True, stdin=subproces s.PIPE, stdout=subproce ss.PIPE,
    stderr=subproce ss.PIPE)
    >
    os.nice(2)
    >
    server.stdin.wr ite('''os.nice( 1)''')
    ----------------------------
    >
    Thanks.
    -Chuckk
    >
    --http://www.badmuthahub bard.com
    Looks like you're dropping an error by redirecting the child process'
    standard error into a pipe.

    First off, remove the stderr=subproce ss.PIPE from
    subprocessclien t.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.StringTyp es):
    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

    Comment

    • Chuckk Hubbard

      #3
      Re: subprocess communication, exec()

      On Tue, Nov 11, 2008 at 9:39 PM, Jeff McNeil <jeff@jmcneil.n etwrote:
      On Nov 11, 1:23 pm, "Chuckk Hubbard" <badmuthahubb.. .@gmail.com>
      wrote:
      >If I run 'python -i subprocessclien t.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?
      >>
      >subprocessserv er.py:
      >----------------------------
      >#!/usr/bin/python2.5
      >>
      >import os
      >import sys
      >>
      >while True:
      > next_line = sys.stdin.readl ine()
      > if not next_line:
      > break
      > exec(next_line)
      ># sys.stdout.writ e(output)
      ># sys.stdout.writ e(next_line)
      ># sys.stdout.flus h()
      >----------------------------
      >>
      >subprocessclie nt.py:
      >----------------------------
      >#!/usr/bin/python2.5
      >>
      >import subprocess, os
      >>
      >server = subprocess.Pope n(('python2.5', 'subprocessserv er.py'),
      >shell=True, stdin=subproces s.PIPE, stdout=subproce ss.PIPE,
      >stderr=subproc ess.PIPE)
      >>
      >os.nice(2)
      >>
      >server.stdin.w rite('''os.nice (1)''')
      >----------------------------
      >>
      >Thanks.
      >-Chuckk
      >>
      >--http://www.badmuthahub bard.com
      >
      Looks like you're dropping an error by redirecting the child process'
      standard error into a pipe.
      >
      First off, remove the stderr=subproce ss.PIPE from
      subprocessclien t.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.StringTyp es):
      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

      --

      Comment

      Working...