2012-01-27 47 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

相關問題