2016-11-28 71 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