Getting subprocess.call() output into a string?

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

    Getting subprocess.call() output into a string?

    I am not sure how to capture the output of a command
    using subprocess without creating a temp file. I was
    trying this:

    import StringIO
    import subprocess

    file = StringIO.String IO()

    subprocess.call ("ls", stdout = file)

    Traceback (most recent call last):
    File "<stdin>", line 6, in ?
    File "/usr/local/lib/python2.4/subprocess.py", line 413, in call
    return Popen(*args, **kwargs).wait( )
    File "/usr/local/lib/python2.4/subprocess.py", line 534, in __init__
    (p2cread, p2cwrite,
    File "/usr/local/lib/python2.4/subprocess.py", line 840, in _get_handles
    c2pwrite = stdout.fileno()
    AttributeError: StringIO instance has no attribute 'fileno'

    So how do I get the output into a string?

    I thought that the idea of StringIO was that it could be
    used where a file was expected.

    Thanks,

    Toby
    ** Posted from http://www.teranews.com **
  • David

    #2
    Re: Getting subprocess.call () output into a string?

    On Tue, Apr 15, 2008 at 10:36 PM, Tobiah <toby@tobiah.or gwrote:
    I am not sure how to capture the output of a command
    using subprocess without creating a temp file. I was
    trying this:
    >
    import StringIO
    import subprocess
    >
    file = StringIO.String IO()
    >
    subprocess.call ("ls", stdout = file)
    >
    Traceback (most recent call last):
    File "<stdin>", line 6, in ?
    File "/usr/local/lib/python2.4/subprocess.py", line 413, in call
    return Popen(*args, **kwargs).wait( )
    File "/usr/local/lib/python2.4/subprocess.py", line 534, in __init__
    (p2cread, p2cwrite,
    File "/usr/local/lib/python2.4/subprocess.py", line 840, in _get_handles
    c2pwrite = stdout.fileno()
    AttributeError: StringIO instance has no attribute 'fileno'
    >
    So how do I get the output into a string?
    >
    I thought that the idea of StringIO was that it could be
    used where a file was expected.
    >
    For basic file-like read and write. But it won't provide a file handle
    since there is no 'real' file. Also, from 2.3.9 File Objects:
    "File-like objects which do not have a real file descriptor should not
    provide this method!"

    You should use the PIPE subprocess argument to capture output. From
    the tutorial:

    6.8.3.1 Replacing /bin/sh shell backquote
    output=`mycmd myarg`
    ==>
    output = Popen(["mycmd", "myarg"], stdout=PIPE).co mmunicate()[0]

    Comment

    • Tobiah

      #3
      Re: Getting subprocess.call () output into a string?

      On Tue, 15 Apr 2008 13:36:11 -0700, Tobiah wrote:
      I am not sure how to capture the output of a command
      using subprocess without creating a temp file. I was
      Sorry, I jumped into a secondary level of the
      docs, and didn't see it all. I guess I can
      use communicate() to get the output.

      Still, about StringIO...

      trying this:
      >
      import StringIO
      import subprocess
      >
      file = StringIO.String IO()
      >
      subprocess.call ("ls", stdout = file)
      >
      Traceback (most recent call last):
      File "<stdin>", line 6, in ?
      File "/usr/local/lib/python2.4/subprocess.py", line 413, in call
      return Popen(*args, **kwargs).wait( )
      File "/usr/local/lib/python2.4/subprocess.py", line 534, in __init__
      (p2cread, p2cwrite,
      File "/usr/local/lib/python2.4/subprocess.py", line 840, in _get_handles
      c2pwrite = stdout.fileno()
      AttributeError: StringIO instance has no attribute 'fileno'
      >
      So how do I get the output into a string?
      >
      I thought that the idea of StringIO was that it could be
      used where a file was expected.
      >
      Thanks,
      >
      Toby
      ** Posted from http://www.teranews.com **
      ** Posted from http://www.teranews.com **

      Comment

      • David

        #4
        Re: Getting subprocess.call () output into a string?

        >
        Still, about StringIO...
        >
        The module description says you can use it to read and write strings
        as files, not that you can use strings *everywhere* you can use files.

        In your specific case, StringIO doesn't work, because the stdout
        redirection takes place at the operating system level (which uses real
        file handles), rather than in a python library (for which StringIO
        would probably work).

        David.

        Comment

        • Nick Stinemates

          #5
          Re: Getting subprocess.call () output into a string?

          On Tue, Apr 15, 2008 at 11:16:01PM +0200, David wrote:

          Still, about StringIO...
          >
          The module description says you can use it to read and write strings
          as files, not that you can use strings *everywhere* you can use files.
          >
          In your specific case, StringIO doesn't work, because the stdout
          redirection takes place at the operating system level (which uses real
          file handles), rather than in a python library (for which StringIO
          would probably work).
          >
          David.
          --
          http://mail.python.org/mailman/listinfo/python-list
          Just a note to all of those who are interested.

          I have yet to get this to work properly for an app which runs indefinitely and you want to read the output at a specified interval. Right now the only way I can read is if the _close() method has been called.

          Anyway, I wrote a wrapper around it so I could easily change the
          implementation if I could ever find a better solution. Here's my code:


          =============== ============
          import subprocess
          import os
          import select

          class ProcessMonitor:
          def __init__(self):
          self.__process = None
          self.__stdin = None
          self.__stdout = None

          def _create(self, process):
          self.__process = subprocess.Pope n(process, stdin=subproces s.PIPE, stdout=subproce ss.PIPE, close_fds=True)
          self.__stdin = self.__process. stdout

          self.__stdout = self.__process. stdout


          def _close(self):
          os.kill(self.__ process.pid,9)

          def _listen(self):
          """
          get from stdout
          """
          return "".join(self.__ stdout.readline s())

          def _listen2(self):
          """
          My attempt at trying different things.
          """
          inp, out = self.__process. communicate("")
          print out


          --
          Nick Stinemates (nick@stinemate s.org)

          Comment

          Working...