Как обнаружить ввод, введенный из bash в фоновом процессе, используя std :: in и getline () - PullRequest
0 голосов
/ 17 мая 2018

У меня есть двоичный файл, скомпилированный в Cpp со следующим кодом:

std::string input;
getline(std::cin, input);
std::cout << "Message given: " << input << std::endl;

Если я выполню этот пример и напишу в терминале «Hello world!»отлично работает:

Message given: Hello world!

Теперь я запускаю исполняемый файл с перенаправлением stdout:

./basicsample >> output/test

Если я пытаюсь ввести ввод с помощью файлового дескриптора:

echo "Hello world!" > /proc/${PID}/fd/0

Сообщение появляется в терминале, который запустил процесс:

[vgonisanz@foovar bash]$ ./basicsample >> output/test
Hello world!

Но сообщение не появляется в выходных данных программ.Я ожидаю, что сообщение будет обработано getline, но оно не обнаружено!Но, если я напишу прямо в этом bash, программа получит ввод.Я пытаюсь сделать сценарий для ввода входных данных в фоновом процессе, но он не работает.

Как я могу ввести входные данные, которые будут обнаружены в процессе, не делая это вручную?

ОБНОВЛЕНИЕ:

Кажется, что при использовании ожидаемого, это может сработать, но я предпочитаю избегать подобных зависимостей.После нескольких попыток лучший способ сделать это без зависимостей - это использовать канал, например:

mkdir tmp; mkfifo tmp/input.pipe; nohup ./basicsample  tmp/user.out 2> tmp/nohup.err

Это запустит создание канала ввода, вывод для консоли и ошибку.Затем просто подайте трубу, используя:

echo "Hello world!" > tmp/input.pipe

Проблема в том, что труба работает только один раз.После получения ввода, он никогда не будет слушать снова.Может быть, так, но я не знаю, как избежать потери фокуса.

Я пытался перенаправить его несколькими способами, например, файлами и т. Д., Но это не сработало.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Лучший способ сделать это без зависимостей - использовать канал, например:

mkdir tmp
mkfifo tmp/input.pipe
(tail -f tmp/input.pipe) | ./basicsample > tmp/log.0 &

Это запустит создание канала ввода и вывода, сохраненного в файле журнала. Вы можете предотвратить блокировку консоли, используя оператор &, чтобы запустить ее в фоновом режиме.

Затем введите данные, используя:

echo "YOUR_STRING" > tmp/input.pipe

Это должно работать для вашей поставленной задачи.

0 голосов
/ 17 мая 2018

/proc/<pid>/fd/{0,1,2} - это просто символическая ссылка на tty / pty (например, /dev/pts/10).Данные, записанные в tty / pty, не могут служить входными данными ( stdin ) для других процессов.

Вы можете попробовать sexpect или другие -как инструмент.Например:

sock=/tmp/tmp.sock
sexpect -s $sock spawn bash -c './basicsample >> output/test'
sexpect -s $sock send -cstr 'Hello world!\r'
sexpect -s $sock wait

ОБНОВЛЕНИЕ:

Может быть, вы просто хотите это?

echo "hello world" | ./basicsample >> output/test
...