如何使用Python中的子进程模块与生成的进程动态交互

问题描述 投票:0回答:1

为了提供一些背景信息,我必须对学生的C代码进行评分。这是文件夹结构:

    Root
      |_____ID#1
        |____task1.c
        |____task2.c
        |____task3.c
      |_____ID#2
        |____task1.c
        |____task2.c
        |____task3.c
        ...

请注意,并非每个学生都回答了所有问题,命名惯例也不是统一的。因此,我无法知道哪个文件包含哪个任务。所有任务都需要某种用户输入,但是由于我不知道哪个文件包含哪个任务,因此无法通过计算文件名来对输入进行硬编码。

我希望能够保存:

a。流程的输入,我必须能够以交互的方式提供给它们(请在“代码编译”之后考虑以下屏幕截图,以了解交互性),

enter image description here

b。处理输入后的输出,

c。他们的错误(如果有)

现在是json甚至是文本文件。

这是我到目前为止所拥有的:

import os
import subprocess
from zipfile import ZipFile

student_folders_root = "/home/mahieyin/Documents/Code/Python/CSE115/Mid #1-20200403T150847Z-001/Mid #1/"

for idx, (directory, _, zipfiles) in enumerate(os.walk(student_folders_root)):
    result = ""
    student_id = directory.rsplit(os.sep, 1)[-1]

    if idx == 0:
        continue
    elif len(zipfiles) == 0:        
        result += f"{student_id} did not attend the mid term exam."
        print(result)
    else:
        zipfiles = list(filter(lambda x: x.endswith(".zip"), zipfiles))

        path_to_zip = os.path.join(directory, *zipfiles)

        if path_to_zip.endswith('.zip'):
            with ZipFile(path_to_zip, 'r') as zip_object:
                zip_object.extractall(directory)

        print(f"\033[1;33;40mProcessing student: {student_id}...")

        for _, _, files in os.walk(directory):
            files = list(filter(lambda x: x.endswith('.c'), files))
            files = list(map(lambda x: os.path.join(directory, x), files))

            executable_name = "a.out"
            exec_path = os.path.join(directory, executable_name)

            for c_file in files:
                try:                
                    print(f"\n\n\033[1;35;40mProcessing file: {c_file}", end="\n\n")
                    compile_command = f"gcc \"{c_file}\" -o \"{exec_path}\""
                    run_command = f"\"{exec_path}\""
                    # command = f"gcc \"{c_file}\" -o \"{exec_path}\""

                    # subprocess.call(command, shell=True)
                    compile_result = subprocess.check_output(compile_command, shell=True)
                    compile_result = compile_result.decode('utf-8').strip()

                    if len(compile_result) == 0:
                        print("Code compiles.")                        
                        run_process = subprocess.run(run_command, shell=True)
                    else:
                        print("Compilation error.")
                        print("\033[1;31;40m", compile_result)
                except subprocess.CalledProcessError:
                    pass

这按预期工作。如果源文件无法编译,我会看到编译错误。我可以向生成的进程提供输入并查看输出。但是,在保持交互性的同时,我无法全力以赴地获取输出信息。

[基本上,每当我尝试在stdoutstderr中设置subprocess.Popen()subprocess.call()选项时,我都会与生成的进程失去交互性。直到我提供输入之后,生成的进程的提示才会显示(e.g. "Please enter the value: "),这看起来并不好看。

提前感谢。

python-3.x subprocess
1个回答
0
投票

看看pexpect

Pexpect是用于生成子应用程序的纯Python模块;控制他们;并响应其输出中的预期模式。

© www.soinside.com 2019 - 2024. All rights reserved.