aihaiyang
aihaiyang

Reputation: 91

How to provide input to a python subprocess call that expects filename, rather than variable?

I'm trying to call a shell script (segment.sh) within python. The syntax that produce correct results at the console is:

> ./segment.sh ctb file.txt utf-8 0

As can be seen, this shell script expects an text file as input. What I am trying to do is to open up the file and read its content in python (later preferably from an HTML POST form), and somehow pass the variable containing the content to the python subprocess call.

The following function is not working. But if I just provide a file name such as:

Popen(["/bin/bash", "./segment.sh", "ctb", "file.txt", "utf-8", "0"])`

then, it will work, but I want to pass the input from a variable. Would you please give me some pointers?

def pySegment(text):
    op = subprocess.Popen(["/bin/bash", "./segment.sh", "ctb", "utf-8", "0"],
                      stdout = subprocess.PIPE,
                      stdin  = subprocess.PIPE,
                      stderr = subprocess.STDOUT,                          
                      )
    results = op.communicate(input=text)[0]
    return results

if __name__ == "__main__":
    filename = "./file.txt"
    text = open(filename).read()
    result = pySegment(text)
    print result

Upvotes: 4

Views: 3635

Answers (1)

jcollado
jcollado

Reputation: 40384

I suggest to use a named pipe:

import os, tempfile, shutil, subprocess

temp_dir = tempfile.mkdtemp()
filename = os.path.join(temp_dir, 'file.txt')
text = '<text>'
os.mkfifo(filename)

try:
    subprocess.Popen(('segment.sh', 'ctf', filename, 'utf-8', '0'))
    with open(filename, 'w') as f:
        f.write(text)
finally:
    shutil.rmtree(temp_dir)

The named pipe will offer the same interface of a file without really creating that file as you need.

Upvotes: 5

Related Questions