Как обеспечить ввод для вызова подпроцесса python, который ожидает имя файла, а не переменную? - PullRequest
4 голосов
/ 27 января 2012

Я пытаюсь вызвать сценарий оболочки (сегмент.ш) в Python. Синтаксис, который дает правильные результаты на консоли:

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

Как видно, этот сценарий оболочки ожидает текстовый файл в качестве входных данных. Я пытаюсь открыть файл и прочитать его содержимое на python (позже желательно из формы HTML POST) и каким-то образом передать переменную, содержащую содержимое, в подпроцесс python. звоните.

Следующая функция не работает. Но если я просто предоставлю имя файла, например:

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

тогда это будет работать, но я хочу передать входные данные из переменной. Не могли бы вы дать мне несколько советов?

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

1 Ответ

5 голосов
/ 27 января 2012

Я предлагаю использовать именованный канал :

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)

Именованный канал предложит тот же интерфейс файла без реального создания этого файла, как вам нужно.

...