2

Is there a way to simulate ENTER key in a bash script imputing values to a code through a here-document (EOF). Readily possible in bash, see question 6264596.

Pseudo code:

 #!/bin/bash
 code_executable << EOF
 value1
 value2 
 EOF

value2 needs to be followed by a carriage return, ie ENTER when executing from a shell.

Thanks guys.

Simulation of executable running on a terminal:

  $./code_executable
  >Do you want to continue? yes or no
  User: y
  >Enter number:
  User: 314 

If User doesn't press ENTER on keyboard after entering 314, executable hangs/halts there and waits.

Edit: see exceptions in stdin buffering that prevent the EOF from passing arguments to an executable as illustrated by @that other guy answer below.

Community
  • 1
  • 1
slkuser
  • 63
  • 1
  • 6
  • 2
    Do you just want a blank line after `value2` but before `EOF`? – chepner Aug 02 '16 at 18:06
  • @chepner: I'm not sure. I added a literal blank line between `value2` and EOF and still not solved, executable can't get `value2`. – slkuser Aug 02 '16 at 18:14
  • 2
    Maybe there's a bug in the executable? With the script as shown in the question, the executable should see a line `"value1\n"`, followed by a line `"value2\n"`, followed by an end-of-file condition. Adding a blank line between `value2` and `EOF` should give the executable an additional line `"\n"`. What happens when you run the executable by itself and give it input from the keyboard? – Keith Thompson Aug 02 '16 at 18:16
  • @ Keith Thompson: no bug in executable. `value1` is fetched without waiting for carriage return, while `value2` is not. This what happens when run from a terminal: ask for `value1` then upon "typing" the latter immediately follows instruction to impute `value2` which stays there until typing ENTER. – slkuser Aug 02 '16 at 18:27
  • I didn't down-vote, but your question lacks clarity. Also, please add clarifications _directly to your question_, not in comments. I couldn't make sense of you most recent comment describing the interactive behavior. – mklement0 Aug 02 '16 at 18:48
  • 1
    Mayhaps `code_exacutable` is `FTP.EXE` or similar? Programs that read from /dev/tty cannot be redirected this way. – Zsigmond Lőrinczy Aug 02 '16 at 18:59
  • Your example does not show what happens after pressing 314 and pressing enter. Do you drop back to the prompt or do you have to type QUIT, EXIT or Ctrl-C to exit code_executable? What is code_executable anyway, homegrown or a known program? Showing an actual running of it with input and output from start to finish indicating exactly what you had to type may help. – Gary_W Aug 02 '16 at 19:37
  • @Gary: when pressing `314`, now-famous executable (homegrown C++) finishes its job on the terminal. No need to further intervention from user. – slkuser Aug 02 '16 at 20:03

2 Answers2

4

Enter is normally represented by a linefeed, not a carriage return. Programs are frequently confused by carriage returns, so terminals will automatically translate them to line feeds.

You can see this in a hex dump:

holen@vidarh2 11:14 ~ $ hexdump -C
(press enter several times, end with ctrl+d)
00000000  0a 0a 0a 0a                                       |....|
           ^----------- line feeds

If you look at your script, you can see that it already adds one after value2 and your trailing space:

$ cat yourscript 
#!/bin/bash
hexdump -C << EOF
value1
value2 
EOF

$ ./yourscript 
00000000  76 61 6c 75 65 31 0a 76  61 6c 75 65 32 20 0a     |value1.value2 .|
                                        line feed ----^

Here's an example of this working:

$ ./ex1
Continue?
yes
Number?
123
You wrote: 123

$ ./ex1 << EOF
> yes
> 123
> EOF
Continue?
Number?
You wrote: 123

Here's an example of this failing due to a buffering bug in the program, even though the program appears to work exactly the same when run interactively but receives wrong input:

$ ./ex2
Continue?
yes
Number?
123
You wrote: 123

$ ./ex2 << EOF
yes
123
EOF

Continue?
Number?
You wrote: yes

Here's a third example of a different kind of buffering bug, where the program works the same interactively but appears to receive no input from a here document:

$ ./ex3
Continue?
yes
Number?
123
You wrote: 123

$ ./ex3 << EOF
yes
123
EOF
Continue?
Number?
You wrote: 

They read lines with fscanf(stdin, ..), fdopen(0, "r"); fscanf(file, ... and read(0, buffer, 1024) respectively. Only the first one is correct.

that other guy
  • 116,971
  • 11
  • 170
  • 194
  • @ other guy: please see my comment above. Thanks for the explanation. However, it does not suggest a resolution. – slkuser Aug 02 '16 at 18:36
  • Yes it does, just not to your implicit follow-up "why isn't my secret program interpreting the enter key press that is correctly added?" – that other guy Aug 02 '16 at 19:12
  • @ : I don't think I understand your comment. I clarified the question with a simulated execution from the terminal. – slkuser Aug 02 '16 at 19:25
  • 1
    @slkuser Still sounds like a bug in your program. I added an example of three programs that work identically when running interactively, where only one works with a here document. Non-interactive programs have different buffering and timing behavior that buggy programs may rely on. – that other guy Aug 02 '16 at 20:44
  • 1
    @ other guy: thanks so much for the detailed debugging. The executable in question uses non of the stdin functions you pointed to..rather a custom defined one to do the read-line. And indeed it behaves like the non-working situations. – slkuser Aug 03 '16 at 05:32
  • 1
    @slkuser: I suggest you (a) add a big disclaimer at the top of your question that your specific problem cannot be solved as presented, because the problem lies _elsewhere_, (b) _accept this answer_, because it answers the question _as asked_ (and additionally provides great pointers as to what the true problem may be), (c) open a new question, in which you ask why your custom-defined read-line function doesn't works as expected. – mklement0 Aug 03 '16 at 14:06
  • @ other guy. This question is non-trivial as you demonstrated and it is answered by @ mklement0 below as far as EOF+RETURN is concerned. I removed the edit note to reflect that it has been answered. – slkuser Aug 03 '16 at 16:58
1

* See that other guy's helpful answer for useful background information and tips for what the actual problem may be.
* This answer assumes a well-behaved program that reads prompt inputs from stdin - as it turns out, not using such a program was precisely the OP's problem: their program behaves differently when inputs are provided via stdin as opposed to by interactive typing.

Let's simulate your executable with the following script:

#!/usr/bin/env bash

printf ">Do you want to continue? (y)es or (n)o: "
read -r -n 1  confirm  # NOTE: A *single* keypress terminates input here.
printf "\nUser: $confirm\n"

printf ">Enter number: "
read -r  number
printf "User: $number\n"

To provide the sample input in your question to this script via stdin, using a here-document:

./code_executable <<EOF
y314
EOF

Note the absence of a newline between y and 314 to account for the fact that the 1st prompt does not require an ENTER keypress to commit the input - only a single character.

With a here-document, the overall input invariably ends in a newline (\n), which acts as if Enter had been pressed (as explained in that other guy's helpful answer) and therefore submits the input to the 2nd prompt.

Additional prompt inputs can simply be added before the closing EOF delimiter, with each additional input that requires Enter to submit on its own line.

./code_executable <<EOF
y314
next input
...
EOF
Community
  • 1
  • 1
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • @ mklement0: thanks so much for your suggestion. I tested your solution, to unfortunately no avail. I need to pass several args to executable, hence the use of `EOF`...but I am open to other suggestions. – slkuser Aug 02 '16 at 19:50
  • @slkuser: I've removed the here-string alternative (`<<<`) to avoid confusion. You can simply add additional inputs (that's what I assume you meant by args) to the here-document - please see my update. – mklement0 Aug 02 '16 at 20:01
  • @ mklement0: actually using `y314` instead of `314` did not solve the problem. There are no further user inputs after (but before) this argument that requires press enter. – slkuser Aug 02 '16 at 20:18
  • 1
    The only plausible explanation at this point is that your C++ program doesn't (consistently) read from _stdin_, and perhaps reads prompt inputs from the _terminal_ directly (as has already been suggested). Without knowing what your program truly does, we can't help you. My sample script that simulates your program is well-behaved in terms of reading from stdin, and, as you can tell, it works. – mklement0 Aug 02 '16 at 20:21