2016-11-28 70 views
0

我一直在嘗試運行Java程序並從Python腳本中將其STDOUT輸出捕獲到文件中。這個想法是通過我的程序運行測試文件,並檢查它是否符合答案。使用Python將程序中的輸出重定向到文件:特定錯誤

thisthis SO問題,使用subprocess.call是要走的路。在下面的代碼中,我在做subprocess.call(command, stdout=f),其中f是我打開的文件。

結果文件是空的,我不明白爲什麼。

import glob 

test_path = '/path/to/my/testfiles/' 
class_path = '/path/to/classfiles/' 
jar_path = '/path/to/external_jar/' 
test_pattern = 'test_case*' 
temp_file = 'res' 

tests = glob.glob(test_path + test_pattern) # find all test files 

for i, tc in enumerate(tests): 
    with open(test_path+temp_file, 'w') as f: 
     # cd into directory where the class files are and run the program 
     command = 'cd {p} ; java -cp {cp} package.MyProgram {tc_p}' 
               .format(p=class_path, 
                 cp=jar_path, 
                 tc_p=test_path + tc) 
     # execute the command and direct all STDOUT to file 
     subprocess.call(command.split(), stdout=f, stderr=subprocess.STDOUT) 
    # diff is just a lambda func that uses os.system('diff') 
    exec_code = diff(answers[i], test_path + temp_file) 
    if exec_code == BAD: 
     scream(':(') 
+0

有很多原因,你的文件是空的第一...通過替換在命令行中與實際值的變量執行的命令,看看你'使用正確的命令! –

+0

我試過了,命令是正確的。我也嘗試使用w/o分割命令並傳遞'''shell = True'''。我也試過'''subprocess.check_call(command.split(),stdout = PIPE)'''狀態爲0(成功)。 –

+0

你有寫訪問該文件/目錄嗎? –

回答

0

我檢查docssubprocess和他們建議使用subprocess.run(在Python 3.5添加)。 run方法返回CompletedProcess的實例,該實例有一個stdout字段。我檢查了它,stdout是一個空字符串。這解釋了爲什麼我試圖創建的文件f是空的。

儘管subprocess.call退出代碼爲0(成功),但這並不意味着我的Java程序實際上得到執行。我最終通過將command分爲兩部分來修復此錯誤。

如果你注意到,我最初試圖cd到正確的目錄,然後執行Java文件 - 全部在一個command。我最終從command中刪除了cd,而是做了os.chdir(class_path)command現在只包含用於運行Java程序的字符串。這個伎倆。

因此,代碼是這樣的:

good_code = 0 
# Assume the same variables defined as in the original question 
os.chdir(class_path) # get into the class files directory first 
for i, tc in enumerate(tests): 
    with open(test_path+temp_file, 'w') as f: 
     # run the program 
     command = 'java -cp {cp} package.MyProgram {tc_p}' 
                .format(cp=jar_path, 
                tc_p=test_path + tc) 
     # runs the command and redirects it into the file f 
     # stores the instance of CompletedProcess 
     out = subprocess.run(command.split(), stdout=f) 
     # you can access useful info now 
     assert out.returncode == good_code