Проблема со сценарием ввода с помощью perl -e 'print'
Я пытаюсь автоматизировать ввод в программу с помощью perl, вводя в командной строке perl -e 'print "1\n5\nn\n5\n"' | ./game_of_chance
.
Но в конце вывода функции print почему то программа останавливается, и ввести что-либо невозможно
Должно быть:
Проблема вряд ли в программе, тк если я выберу сценарий, в котором print заканичвается на выборе цифры в игре, то тоже возникнет проблема, хоть и слегка другая:
В идеале после выбора игры должно быть:
После выбора цифры:
При этом, если последним действием я поставлю выбрать пункт "7" в меню (то есть выход), то все действия в списке завершатся корректно. Что интересно при этом можно даже не ставить \n в конце (perl -e 'print "1\n5\nn\n7"' | ./game_of_chance
), хотя логика программы требует подтвердить действия с помощью Enter
Ответы (2 шт):
"Подскажите, пожалуйста, как это сделать?"
Поскольку речь идет о вводе с терминала, то это не сложно, т.к. широко известно, что в *nix-ах терминал, с которого запущена программа, имеет в ней имя /dev/tty.
Просто откроем его и свяжем наш уже существующий FILE *stdin
с новым дескриптором.
Для того, чтобы новый stdin оказался связанным с используемым по умолчанию для stdin дескриптором с номером 0 используем вызов dup2, а чтобы не плодить не используемые дескрипторы закроем уже дапнутый дескиптор, полученный от открытого /dev/tty
(надеюсь, что вам, как начинающему хакеру, юзающему эксплойты, не составит большого труда разобраться в этих нехитрых системных манипуляциях)
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int
main (int ac, char *av[])
{
char s[1000];
while (fgets(s, 1000, stdin))
printf("s = %s", s);
puts("\nstdin EOF, reopen tty");
int fd = open("/dev/tty", O_RDONLY);
stdin = fdopen(dup2(fd, 0), "r");
close(fd);
puts("Enter lines:");
while (fgets(s, 1000, stdin))
printf("s: %s", s);
return puts("End") == EOF;
}
Если я правильно понял вашу проблему, то вам должен подойти модуль Term::ReadKey и/или Term::ReadLine
use v5.26.0;
use warnings;
use Term::ReadKey;
ReadMode 4; # Turn off controls keys
my $key;
while (not defined ($key = ReadKey(-1))) {
# No key yet
}
print "Get key $key\n";
ReadMode 0; # Reset tty mode before exiting
Подробности, как всегда, на metacpan: https://metacpan.org/pod/Term::ReadKey