Search code examples
c++bashshfile-descriptorio-redirection

How detect a input injected from bash in a background process using std::in and getline()


I have a binary compiled in Cpp with the following code:

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

If I execute this example, and write in the terminal "Hello world!" works perfectly:

Message given: Hello world!

Now, I launch the executable in redirecting stdout:

./basicsample >> output/test

If I try to inject inputs using file descriptor:

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

The message appear in terminal that launched the process:

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

But the message no appear in the programs output. I expect to get the message processed by getline, and it is not detected! But, If I write directly in that bash, the program get the input. I'm trying to do a script to inject inputs in a background process but it is not working.

How could I inject inputs to be detected into the process without do it manually?

UPDATE:

It seems that using expect, this could work, but I will prefer to avoid dependencies like this. After several tries, the best way to do it without dependencies is to use a pipe, in example:

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

This will run the creating a input pipe, an output for console and error. Then, just feed the pipe using:

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

The problem of this is, the pipe works only once. After getting an input, it won't never listen it again. Maybe this is the way but I don't know how to avoid to lost the focus.

I tried to redirect it using several ways like files, etc, but it doesn't works. Thanks in advance.


Solution

  • The best way to do it without dependencies is to use a pipe, in example:

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

    This will run creating an input pipe and an output saved in log file. You can prevent console blocking using the operator & to launch it in background.

    Then inject data using:

    echo "YOUR_STRING" > tmp/input.pipe
    

    It should work for your posed problem.