Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use StringIO as stdin with Popen

Tags:

I have the following shell script that I would like to write in Python (of course grep . is actually a much more complex command):

#!/bin/bash

(cat somefile 2>/dev/null || (echo 'somefile not found'; cat logfile)) \
| grep .

I tried this (which lacks an equivalent to cat logfile anyway):

#!/usr/bin/env python

import StringIO
import subprocess

try:
    myfile = open('somefile')
except:
    myfile = StringIO.StringIO('somefile not found')

subprocess.call(['grep', '.'], stdin = myfile)

But I get the error AttributeError: StringIO instance has no attribute 'fileno'.

I know I should use subprocess.communicate() instead of StringIO to send strings to the grep process, but I don't know how to mix both strings and files.

like image 881
Suzanne Soy Avatar asked Dec 13 '13 13:12

Suzanne Soy


People also ask

How do I write to a python subprocess stdin?

To write to a Python subprocess' stdin, we can use the communicate method. to call Popen with the command we want to run in a list. And we set stdout , stdin , and stderr all to PIPE to pipe them to their default locations.

What is StringIO StringIO?

The StringIO module is an in-memory file-like object. This object can be used as input or output to the most function that would expect a standard file object. When the StringIO object is created it is initialized by passing a string to the constructor. If no string is passed the StringIO will start empty.

Does Popen need to be closed?

Popen do we need to close the connection or subprocess automatically closes the connection? Usually, the examples in the official documentation are complete. There the connection is not closed. So you do not need to close most probably.


1 Answers

p = subprocess.Popen(['grep', '...'], stdin=subprocess.PIPE, 
                                      stdout=subprocess.PIPE)
output, output_err = p.communicate(myfile.read())
like image 191
Ski Avatar answered Oct 21 '22 11:10

Ski