My console program runs under Ubuntu 20.04. When run interactively, the input expression (e.g., a+b below) is displayed next to the prompt followed by the output on a new line as follows. I would like to achieve this same format when providing the input to the program from a bash script.
$ ./rec_desc1
Enter expression: a+b
F --> id
R --> eps
T --> FR
F --> id
R --> eps
T --> FR
Q --> eps
Q --> +TQ
E --> TQ
Success.
But if I send the input from a bash script via here-string or piping it (as suggested at How do I provide input to a C program from bash?), the input is not displayed and unfortunately the first line of output is shifted up next to prompt as shown below.
cat rec_desc1_unit_test
#!/bin/bash
echo "Test case 1"
./rec_desc1 <<< a+b
$ ./rec_desc1_unit_test
Test case 1
Enter expression: F --> id
R --> eps
T --> FR
F --> id
R --> eps
T --> FR
Q --> eps
Q --> +TQ
E --> TQ
Success.
Is there a way to pass the input from a bash script so that it displays next to the prompt and is followed by a newline so it matches the interactive case above?
I eventually want to run numerous test cases for different expressions from a bash script and would like to have the self-documentation of the input expression being displayed. I could call set -v prior to invoking the console program in order to display the input if necessary (as shown below). Then I would need to call set +v immediately afterward to avoid displaying the echo statements that describe the next test case. I would like to avoid surrounding each test case with set -v and set +v if possible.
$ cat rec_desc1_unit_test
#!/bin/bash
echo "Test case 1"
set -v
./rec_desc1 <<< a+b
$ ./rec_desc1_unit_test
Test case 1
./rec_desc1 <<< a+b
Enter expression: F --> id
R --> eps
T --> FR
F --> id
R --> eps
T --> FR
Q --> eps
Q --> +TQ
E --> TQ
Success.
2
Answers
You’ll have to post-process the output; making the whole thing a shell function might be a good idea:
The fact that rec_desc1 is a C program, and what it does with it’s input is irrelevant to your question assuming you don’t want that to change.
Here’s a shell script that produces the behavior you describe, i.e. prompts for input and produces some output based on that input (in this case print a series of numbers):
Here it is being run manually:
Here is the equivalent of your test script calling it:
and the output that produces:
Now, here is a modified version of your caller test script:
and the output that produces:
That uses a coprocess to run
./rec_desc1
feeding it input from the calling script and reading it’s output into the calling script. Alternatively you could useexpect
to do the same.The above relies on
run_desc1
sending prompts and other status messages to stderr as it should. If it doesn’t do that then you need a little different solution to read the prompt, etc. but that’s complicated by the fact that the prompt doesn’t end in a newline whileread
only reads newline-terminated lines so you’d need to use a different solution than justread
to read the output fromrun_desc1
.