Я пытаюсь создать программу, которая принимает имя исполняемого файла в качестве аргумента, запускает исполняемый файл и сообщает о входных и выходных данных для этого запуска. Например, рассмотрим дочернюю программу с именем 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
. У него есть метод с именем interact
, который позволяет пользователь взаимодействует с дочерней программой, как показано выше. Он также принимает 2 необязательных параметра: output_filter
и input_filter
. Из документации:
output_filter
будут переданы все выходные данные дочернего процесса.input_filter
будет передан весь ввод с клавиатуры от пользователя.
Итак, это код, который я написал:
Capture_io.py
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;
}
Что производит следующий вывод:
$ 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
запускался только при нажатии Enter
?
Или, в более общем плане, как лучше всего достичь моей цели (с pexpect
или без него)?
script
(отметьте параметры--log-in
и--log-out
) иtee
. - person VPfB   schedule 17.06.2020--log-in
и--log-out
даже на своем компьютере. (script from util-linux 2.31.1
) - person Asocia   schedule 18.06.2020--log-in
, он был добавлен совсем недавно в 2.35. - person VPfB   schedule 18.06.2020bash
, поэтому не знаю, как мне это сделать. В конце концов, единственным требованием является простота. Наличие установленной командыtee
, вероятно, не имеет большого значения, если она решает проблему естественным путем. Когда я набираюman tee
, он говоритCopy standard input to each FILE, and also to standard output.
Итак, похоже, он разделяет входы и выходы. Можно ли объединить эти два, сохраняя порядок (т.е. какой ввод идет после какого вывода и наоборот?) - person Asocia   schedule 18.06.2020