我正在尝试制作一个程序,该程序以可执行文件名作为参数,运行可执行文件并报告该运行的输入和输出。例如,考虑一个名为“ circle”的子程序。我的程序需要运行以下内容:
$ python3 capture_io.py ./circle
Enter radius of circle: 10
Area: 314.158997
[('output', 'Enter radius of circle: '), ('input', '10\n'), ('output', 'Area: 314.158997\n')]
我决定为此工作使用pexpect
模块。它具有一种称为pexpect
的方法,该方法可让用户与子程序进行交互,如上所示。它还具有2个可选参数:interact
和interact
。从文档中:
output_filter
将传递子进程的所有输出。input_filter
将通过用户的所有键盘输入。
这是我写的代码:
output_filter
input_filter
将产生以下输出:
import sys
import pexpect
_stdios = []
def read(data):
_stdios.append(("output", data.decode("utf8")))
return data
def write(data):
_stdios.append(("input", data.decode("utf8")))
return data
def capture_io(argv):
_stdios.clear()
child = pexpect.spawn(argv)
child.interact(input_filter=write, output_filter=read)
child.wait()
return _stdios
if __name__ == '__main__':
stdios_of_child = capture_io(sys.argv[1:])
print(stdios_of_child)
您可以从输出中看到,#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
float radius, area;
printf("Enter radius of circle: ");
scanf("%f", &radius);
if (radius < 0) {
fprintf(stderr, "Negative radius values are not allowed.\n");
exit(1);
}
area = 3.14159 * radius * radius;
printf("Area: %f\n", area);
return 0;
}
功能是在every键上运行的,这让我感到一团糟。是否可以更改此行为,以便仅在按下$ python3 capture_io.py ./circle
Enter radius of circle: 10
Area: 314.158997
[('output', 'Enter radius of circle: '), ('input', '1'), ('output', '1'), ('input', '0'), ('output', '0'), ('input', '\r'), ('output', '\r\n'), ('output', 'Area: 314.158997\r\n')]
时才能运行input_filter
?
或更笼统地说,实现我的目标的最佳方法是什么(有input_filter
有无)?
我认为您不能轻松做到这一点,但是,我认为这应该对您有用:
Enter