Vamsi
Vamsi

Reputation: 87

Input stdin of c program using bash

I made a c program which takes two standard inputs automatically and one manually.

#include <stdio.h>

int main()
{
        int i, j;
        scanf("%d %d", &i, &j);
        printf("Automatically entered %d %d\n", i, j);

        int k;
        scanf("%d", &k);
        printf("Manually entered %d", k);

        return 0;
}

I want to run this program using bash script which can input first two inputs automatically and leaves one input that is to be entered manually. This is the script I am using.

#!/bin/bash

./test <<EOF
1
2
EOF

The problem is EOF is passed as third input instead of asking for manual input. I cannot change my c program and I cannot input third input before the two inputs, so how can I do this using bash. I am new to bash scripting please help.

Upvotes: 2

Views: 1233

Answers (2)

John Bollinger
John Bollinger

Reputation: 180201

I made a c program which takes two standard inputs automatically and one manually.

No, you didn't. You made a program that attempts to read three whitespace-delimited decimal integers from the standard input stream. The program cannot distinguish between different origins of those integers.

The problem is EOF is passed as third input instead of asking for manual input.

No, the problem is that you are redirecting the program's standard input to be a shell here document. The here document provides the whole standard input, similar to if your program were reading a file with the here document's contents. When it reaches the end, it does not fall back to reading anything else.

I cannot change my c program and I cannot input third input before the two inputs

I take those two statements to be redundant: you cannot alter the program so that the input you characterize as "manual" is the first one it attempts to read. Not that that would help, anyway.

What you need to do is prepend the fixed input to the terminal input in the test program's standard input stream. There are many ways to do that, but the cat command (mnemonic for concatenate) seems like a natural choice. That would work together with process substitution to achieve your objective. For example,

#!/bin/bash

cat <(echo 1 2) - | ./test

The <(echo 1 2) part executes echo 1 2 and provides its standard output as if it were a file. The cat command concatenates that with its own standard input (represented by -), emitting its result to its standard output. The result is piped into program ./test.

This provides a means to prepend fixed input under your control to arbitrary data read from the standard input. That is, the wrapper script doesn't need to know what input the program expects after the fixed initial part.

Upvotes: 6

rcwnd_cz
rcwnd_cz

Reputation: 1016

Your problem is not caused by EOF being passed as third argument, but actually because stdin for your command is closed before third call to scanf.

One way how to solve this, is reading the value inside the script and then passing all three of them.

Something like this:

#!/bin/bash

read value
printf '1 2 %s' "$value" | ./test

Upvotes: 4

Related Questions