I have a near-identical problem to one asked several years ago : Python subprocess with two inputs which received one answer but no implemention. I'm hoping that this repost may help clear things up for me and others.
As in the above, I would like to use subprocess to wrap a command-line tool that takes multiple inputs. In particular, I want to avoid writing the input files to disk, but would rather use e.g. named pipes, as alluded to in the above. That should read "learn how to" as I admittedly I have never tried using named pipes before. I'll further state that the inputs I have are currently two pandas dataframes, and I'd like to get one back as output.
The generic command-line implementation:
/usr/local/bin/my_command inputfileA.csv inputfileB.csv -o outputfile
My current implementation, predictably, doesn't work. I don't see how/when the dataframes get sent to the command process through the named pipes, and I'd appreciate some help!
import os
import StringIO
import subprocess
import pandas as pd
dfA = pd.DataFrame([[1,2,3],[3,4,5]], columns=["A","B","C"])
dfB = pd.DataFrame([[5,6,7],[6,7,8]], columns=["A","B","C"])
# make two FIFOs to host the dataframes
fnA = 'inputA'; os.mkfifo(fnA); ffA = open(fnA,"w")
fnB = 'inputB'; os.mkfifo(fnB); ffB = open(fnB,"w")
# don't know if I need to make two subprocesses to pipe inputs
ppA = subprocess.Popen("echo",
stdin =subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
ppB = subprocess.Popen("echo",
stdin = suprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
ppA.communicate(input = dfA.to_csv(header=False,index=False,sep="\t"))
ppB.communicate(input = dfB.to_csv(header=False,index=False,sep="\t"))
pope = subprocess.Popen(["/usr/local/bin/my_command",
fnA,fnB,"stdout"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(out,err) = pope.communicate()
try:
out = pd.read_csv(StringIO.StringIO(out), header=None,sep="\t")
except ValueError: # fail
out = ""
print("\n###command failed###\n")
os.unlink(fnA); os.remove(fnA)
os.unlink(fnB); os.remove(fnB)