2012-01-27 33 views
3

我想在Python中调用shell脚本(segment.sh)。 ,在控制台产生正确的结果的语法为:如何为需要文件名而不是变量的python子进程调用提供输入?

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

可以看出,这个shell脚本期待一个文本文件作为输入。我试图做的是打开文件并在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 
+2

如果'segment.sh'实际上打开了您给它并读取其内容的文件名,并且_doesn't不支持从标准输入读取,那么不幸的是,您必须将文本保存到文件或修改'segment.sh'。这是Unix编程思想之一:使每个程序都能够像过滤器一样运行 - 换句话说,它能够从标准输入读取数据并写入标准输出。 – voithos 2012-01-27 05:24:14

+0

感谢您的评论,@voithos。 segment.sh脚本本身正在调用一个java程序:JAVACMD =“java -mx2g -cp $ BASEDIR/seg.jar edu.stanford.nlp.ie.crf.CRFClassifier -sighanCorporaDict $ DATADIR ** - testFile $ file ** - inputEncoding $ enc -sighanPostProcessing true $ ARGS“。 因此,我不确定此程序是否可以接受文件之外的标准输入。请指教。 – aihaiyang 2012-01-27 05:28:00

+0

同样的观点成立。您的脚本正在运行的Java程序需要能够从标准输入读取。看起来你在这里反对你的工具。不幸的是,并非所有程序都是用标准输入/输出来编写的。但是使用这个文件有问题吗?只需在文件上而不是变量上运行'pySegment',然后打开分段文件并读取它。 – voithos 2012-01-27 06:35:31

回答

5

我建议使用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) 

命名管道将提供文件的相同的接口并没有真正创建一个文件,因为你需要。

+0

'os.mkfifo(filename)'可能应该在try/finally之外。为避免冲突,可以使用'tempfile.mkdtemp()'(之后使用'shutil.rmtree()')。 – jfs 2012-01-27 17:21:51

+0

@ J.F.Sebastian不错的建议。非常感谢您的评论。 – jcollado 2012-01-27 18:48:09

+0

@jcollado非常感谢命名管道的代码和建议。这对我来说是新东西。所以文本=''是我可以分配内容的地方被分割的地方,对吧? – aihaiyang 2012-01-27 22:19:50

相关问题