subprocess woes

kj no.email at please.post
Tue Sep 15 19:50:07 EDT 2009


In <mailman.1498.1253057406.2854.python-list at python.org> Chris Rebert <clp2 at rebertia.com> writes:

>On Tue, Sep 15, 2009 at 12:26 PM, kj <no.email at please.post> wrote:
>> I'm trying to write a function, sort_data, that takes as argument
>> the path to a file, and sorts it in place, leaving the last "sentinel"
>> line in its original position (i.e. at the end). =C2=A0Here's what I
>> have (omitting most error-checking code):
>>
>> def sort_data(path, sentinel=3D'.\n'):
>> =C2=A0 =C2=A0tmp_fd, tmp =3D tempfile.mkstemp()
>> =C2=A0 =C2=A0out =3D os.fdopen(tmp_fd, 'wb')
>> =C2=A0 =C2=A0cmd =3D ['/usr/local/bin/sort', '-t', '\t', '-k1,1', '-k2,2'=
>]
>> =C2=A0 =C2=A0p =3D Popen(cmd, stdin=3DPIPE, stdout=3Dout)
>> =C2=A0 =C2=A0in_ =3D file(path, 'r')
>> =C2=A0 =C2=A0while True:
>> =C2=A0 =C2=A0 =C2=A0 =C2=A0line =3D in_.next()
>> =C2=A0 =C2=A0 =C2=A0 =C2=A0if line !=3D sentinel:
>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0p.stdin.write(line)
>> =C2=A0 =C2=A0 =C2=A0 =C2=A0else:
>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break
>> =C2=A0 =C2=A0in_.close()
>> =C2=A0 =C2=A0p.stdin.close()
>> =C2=A0 =C2=A0retcode =3D p.wait()
>> =C2=A0 =C2=A0if retcode !=3D 0:
>> =C2=A0 =C2=A0 =C2=A0 =C2=A0raise CalledProcessError(retcode, cmd)
>> =C2=A0 =C2=A0out.write(sentinel)
>> =C2=A0 =C2=A0out.close()
>> =C2=A0 =C2=A0shutil.move(tmp, path)
>>
>>
>> This works OK, except that it does not catch the stderr from the
>> called sort process. =C2=A0The problem is how to do this. =C2=A0I want to=
> to
>> avoid having to create a new file just to capture this stderr
>> output. =C2=A0I would like instead to capture it to an in-memory buffer.
>> Therefore I tried using a StringIO object as the stderr parameter
>> to Popen, but this resulted in the error "StringIO instance has no
>> attribute 'fileno'".
>>
>> How can I capture stderr in the scenario depicted above?

>Use a pipe by setting stderr=3DPIPE?:

>p =3D Popen(cmd, stdin=3DPIPE, stdout=3Dout, stderr=3DPIPE)
>#...
>error_output =3D p.stderr.read()

Thanks, that did the trick.  Thanks!

kj 



More information about the Python-list mailing list