Проблема со сценарием ввода с помощью 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 шт):

Автор решения: avp

"Подскажите, пожалуйста, как это сделать?"

Поскольку речь идет о вводе с терминала, то это не сложно, т.к. широко известно, что в *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

→ Ссылка