Subprocess confusion: how file-like must stdin be?

Laurent Pointal laurent.pointal at limsi.fr
Fri Aug 18 09:51:55 EDT 2006


Cameron Laird a écrit :
> In article <slrneeassv.c4m.nick at irishsea.home.craig-wood.com>,
> Nick Craig-Wood  <nick at craig-wood.com> wrote:
>> Dennis Lee Bieber <wlfraed at ix.netcom.com> wrote:
>>>  On Thu, 17 Aug 2006 17:16:25 +0000, claird at lairds.us (Cameron Laird)
>>>  declaimed the following in comp.lang.python:
>>>
>>>> Question:
>>>>   import subprocess, StringIO
>>>>
>>>>   input = StringIO.StringIO("abcdefgh\nabc\n")
>>>  	Here you override the builtin function "input()"
>>>>       # I don't know of a compact, evocative, and
>>>>       # cross-platform way to exhibit this behavior.
>>>>       # For now, depend on cat(1).
>>>>   p = subprocess.Popen(["cat"], stdout = subprocess.PIPE, 
>>>> 				stdin = response)
>>>  	Here you specify the non-existant "response" 
>> Assume the OP meant to write this
>>
>>>>> import subprocess, StringIO
>>>>> inp = StringIO.StringIO("abcdefgh\nabc\n")
>>>>> p = subprocess.Popen(["cat"], stdout = subprocess.PIPE, stdin = inp)
>> Traceback (most recent call last):
>>  File "<stdin>", line 1, in ?
>>  File "/usr/lib/python2.4/subprocess.py", line 534, in __init__
>>    (p2cread, p2cwrite,
>>  File "/usr/lib/python2.4/subprocess.py", line 830, in _get_handles
>>    p2cread = stdin.fileno()
>> AttributeError: StringIO instance has no attribute 'fileno'
> 			.
> 			.
> 			.
> Yes; my apologies for the confusion I introduced by "editing
> for publication", and doing it badly.
> 
> Your interactive session does indeed exhibit the behavior that
> puzzles me.  My expectation was that StringIO and the std* 
> parameters to Popen() were made for each other; certainly there
> are many cases where stdout and stderr can be redirected *to* a
> StringIO.  Is it simply the case that stdin demands a more
> file-like object?  While that disappoints me, I certainly can
> program around it.  My question, then:  does stdin effectively
> require something really in the filesystem, or perhaps the
> stdout of a previous subprocess?  Is there no built-in way to
> feed it an in-memory construct?

As this is a pipe at OS level, there may be no other way than using
os-level tools (ie. real files with fileno), maybe creating an anonymous
pipe, writing to it (relying on pipe buffering by the OS to avoid the
creation of a writer thread), and giving this pipe (which should have a
fileno) to the subprocess.Popen stdin parameter.
Such a construction (pipe/writer thread) would be welcome as standard
subprocess tool.


A+

Laurent.




More information about the Python-list mailing list