python-3.x - 如何使用 Python 中的子进程模块与生成的进程动态交互
问题描述
为了提供一些背景信息,我必须对学生的 C 代码进行评分。这是文件夹结构:
Root
|_____ID#1
|____task1.c
|____task2.c
|____task3.c
|_____ID#2
|____task1.c
|____task2.c
|____task3.c
...
需要注意的是,并非每个学生都回答了所有问题,命名约定也不是统一的。所以,我无法知道哪个文件包含哪个任务。所有任务都需要某种用户输入,但由于我不知道哪个文件包含哪个任务,我无法通过找出文件名来硬编码输入。
我希望能够保存:
一种。进程的输入,我必须能够以交互方式提供给它们(在“代码编译”之后,请考虑以下屏幕截图,了解我所说的交互性),
湾。处理输入后的输出,
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
这按预期工作。如果源文件无法编译,我可以看到编译错误。我可以为生成的进程提供输入并查看输出。但是,我无法在保持交互性的同时获得输出的方式。
基本上,每当我尝试在or中设置stdout
andstderr
选项时,我都会失去与衍生进程的交互性。直到我提供了输入之后,生成的进程的提示才会显示出来,这看起来并不优雅。subprocess.Popen()
subprocess.call()
(e.g. "Please enter the value: ")
提前致谢。
解决方案
看看pexpect
:
Pexpect 是一个用于生成子应用程序的纯 Python 模块;控制它们;并响应其输出中的预期模式。
推荐阅读
- c++ - 将函数参数传递给类函数指针参数
- python - django 使用多个会话引擎?
- x86 - AT&T x86 | `xadd %eax, (%ecx)` 有什么作用?
- android - 如何使用fab风格的钻石?
- opencv - 在 OpenCV C++ 中使用 SimpleBlobDetector 时如何处理紧密重叠的关键点?
- ruby - 区分大小写的替换
- javascript - 为什么我不能在 JavaScript 中做 array[-1]?
- python - 除了计算之外,使用现有数据框选择性地构建新数据框
- javascript - Vue/AXIOS 没有完全下载
- java - 数据库 [默认] 未找到驱动程序 - Playframework 1.4.x 中的 MySQL