2

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.

3
  • 2
    @Inian That's definitely not the case here. Man-page for scanf clearly states that any white-space character matches all other white-space characters, until either end of input or first byte which is not a white-space character is found. Commented Apr 20, 2021 at 12:29
  • The answer (assume it exists) woild be the same if the program was written in Cobol, right? So the C tag is irrelevant. Commented Apr 20, 2021 at 14:23
  • I think you want expect. Commented Apr 20, 2021 at 14:42

2 Answers 2

6

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.

Sign up to request clarification or add additional context in comments.

2 Comments

But I am still confused by this "<(echo 1 2) -" can I get any resources where I can learn about these things in depth.
@saivamsi, the bash manual is probably available to you via man bash, or you can look to the online version. As I mentioned in this answer, that particular feature is called "process substitition". It is Bash-specific.
4

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

6 Comments

My problem is I cannot read third input before the two inputs.
@saivamsi: with the script you say you are using (./test <<EOF...) you only type 1 value on the keyboard !!
@saivamsi In that case it is not easily and reliably possible without also changing the C program. But your original question and examples doesn't have this condition.
I am sorry that I haven't explained this condition. Actually we are developing a camera where in order to stream we have to run a program (written in c) which is given by vendor so I cannot change the program. In that program we have to input sensor data and binary path every time we run the program which is same always. After providing sensor data and binary path it opens a socket at particular IP to stream camera. After analysis is done we need to stop stream by entering number "13". I am getting problem at this last number.
@saivamsi please edit the question and put all relevant information there
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.