I’m porting a bash script to python 2.6, and want to replace some code:
cat $( ls -tr xyz_`date +%F`_*.log ) | filter args > bzip2
I guess I want something similar to the “Replacing shell pipe line” example at http://docs.python.org/release/2.6/library/subprocess.html, ala…
p1 = Popen(["filter", "args"], stdin=*?WHAT?*, stdout=PIPE)
p2 = Popen(["bzip2"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]
But, I’m not sure how best to provide p1‘s stdin value so it concatenates the input files. Seems I could add…
p0 = Popen(["cat", "file1", "file2"...], stdout=PIPE)
p1 = ... stdin=p0.stdout ...
…but that seems to be crossing beyond use of (slow, inefficient) pipes to call external programs with significant functionality. (Any decent shell performs the cat internally.)
So, I can imagine a custom class that satisfies the file object API requirements and can therefore be used for p1’s stdin, concatenating arbitrary other file objects. (EDIT: existing answers explain why this isn’t possible)
Does python 2.6 have a mechanism addressing this need/want, or might another Popen to cat be considered perfectly fine in python circles?
Thanks.
You can replace everything that you’re doing with Python code, except for your external utility. That way your program will remain portable as long as your external util is portable. You can also consider turning the C++ program into a library and using Cython to interface with it. As Messa showed,
dateis replaced withtime.strftime, globbing is done withglob.globandcatcan be replaced with reading all the files in the list and writing them to the input of your program. The call tobzip2can be replaced with thebz2module, but that will complicate your program because you’d have to read and write simultaneously. To do that, you need to either usep.communicateor a thread if the data is huge (select.selectwould be a better choice but it won’t work on Windows).Addition: How to detect file input type
You can use either the file extension or the Python bindings for libmagic to detect how the file is compressed. Here’s a code example that does both, and automatically chooses
magicif it is available. You can take the part that suits your needs and adapt it to your needs. Theopen_autodecompressshould detect the mime encoding and open the file with the appropriate decompressor if it is available.