I want to (hopefully easily) write from a bash script to any arbitrary program that is already running via that program's stdin.
Say I have some arbitrary program "Sum", that constantly takes user input from the terminal. Every integer it receives from stdin it adds to the current sum and outputs the new sum. Here's example terminal text of what I mean:
$: ./Sum
Sum: 0
Give me an integer: 2
Sum: 2
Give me an integer: 5
Sum: 7
How would automate this process in a bash script? If I had control of Sum's source code I could let it accept integer arguments. But if I don't have said control of the program, how can I automate the interaction with Sum? Here's a psuedo code of a bash snippet of what I want to do:
In example.sh:
#!/bin/bash
my_program_input_point=./Sum &
echo 2 > my_program_input_point
echo 5 > my_program_input_point
Thus on my terminal screen it would still look like this:
$: ./example.sh
Sum: 0
Give me an integer: 2
Sum: 2
Give me an integer: 5
Sum: 7
The difference is I wouldn't have typed any of it.
It feels like this task should be really easy, because basically anything you can do in a terminal, you can also easily do in a script. Except, apparently, directly interact with an arbitrary process once its started.
This topic answers some aspects of my question by using pipes. However the accepted answer only works if I have control of both programs on each side of the pipe, the "recipient" program is under no obligation to read from the pipe automatically.
This is assuming I can't modify the program/script in question. I also can't write a "pipe reader" script to wrap around the program (Sum), because that wrapper script would still be required to interact with the running process Sum.
The second answer to this question on serverfault.com (written by jfgagne) seems much closer, but I can't seem to get it working. Is there any easier way to do this that I just don't know about?
For information on how to capture and read an arbitrary program's output, see my next question for more information
The most straightforward way is to use a pipeline. The trick is that you can make the lefthand side of the pipeline a compound statement, or a function call. It doesn't have to be just a single command.
or
This lets you do whatever you want to generate the input. You don't have to have it all ahead of time. If you generate the input bit by bit, it'll be fed to
./Sum
bit by bit.You can use a named pipe. Whatever starts
Sum
is responsible for creating the named pipe some place convenient, then startingSum
with the named pipe as its standard input.Then your script could take the name of the pipe as an argument, then treat it as a file it can write to.
Then you could call your script with
client /tmp/pipe
.You can write to the standard input file descriptor of the running process. Here is the same question: https://serverfault.com/questions/178457/can-i-send-some-text-to-the-stdin-of-an-active-process-running-in-a-screen-sessi
You need to write to
/proc/*pid of the program*/fd/0
which is the file descriptor for the standard input of the process with thatpid
. Make sure you have access to do this.