184

I have a bash script that employs the read command to read arguments to commands interactively, for example yes/no options. Is there a way to call this script in a non-interactive script passing default option values as arguments?

It's not just one option that I have to pass to the interactive script.

3
  • 2
    If it is reading from stdin you could pipe in your input
    – lc.
    Commented Jan 18, 2013 at 4:46
  • 4
    As this question gets many duplicates, it is worth pointing out that it doesn't matter in which language the interactive program is written. It could be a C program which reads standard input, or an Erlang application, or whatever. There's something which runs from the command line and obnoxiously demands interactive input, and you'd like to automate it.
    – tripleee
    Commented Mar 16, 2017 at 4:37
  • Of course, if you have control over the obnoxious application, rewrite it so that it can read the answers noninteractively (through a configuration file, command-line options, or whatever). This is much more reliable and robust against changing the order or wording of interactive questions.
    – tripleee
    Commented Jul 26, 2018 at 13:29

5 Answers 5

220

Many ways

pipe your input

echo "yes
no
maybe" | your_program

redirect from a file

your_program < answers.txt

use a here document (this can be very readable)

your_program << ANSWERS
yes
no
maybe
ANSWERS

use a here string

your_program <<< $'yes\nno\nmaybe\n'
11
  • 7
    It bears pointing out that this only works if the program reads standard input. Some programs go out of their way to read e.g. passwords interactively, even when standard input is a pipe. For passwords, this makes sense for security reasons; though some interactive programs are just simply poorly designed.
    – tripleee
    Commented Mar 16, 2017 at 5:02
  • @tripleee Along the lines of what you said, how does a script read passwords that is not affected by stdin? I know you can use read to grab stdin, what function can you use do what you described?
    – flow2k
    Commented Oct 17, 2017 at 19:03
  • In that case, you need to see if the program you're trying to interact with has a special way to send the input to it (e.g. sshpass, ssh-agent), or use expect to script the interaction. Commented Oct 17, 2017 at 19:40
  • 2
    What programs like Expect do is run the client under a pseudo-tty where it looks to the client like there is a user with a terminal and a keyboard at the other end. You can't do that with a regular pipe.
    – tripleee
    Commented Oct 18, 2017 at 3:47
  • 1
    Or better, avoid echo -e; printf '%s\n' i 2 y y | your_command. Putting all the input on a single line obviously only passes in one line of input, i.e. answers the first prompt with all the text.
    – tripleee
    Commented Mar 24, 2023 at 10:42
67

For more complex tasks there is expect ( http://en.wikipedia.org/wiki/Expect ). It basically simulates a user, you can code a script how to react to specific program outputs and related stuff.

This also works in cases like ssh that prohibits piping passwords to it.

1
  • 15
    ... Though the proper solution in the SSH case is to switch to public-key authentication.
    – tripleee
    Commented Mar 16, 2017 at 4:59
20

You can put the data in a file and re-direct it like this:

$ cat file.sh
#!/bin/bash

read x
read y
echo $x
echo $y

Data for the script:

$ cat data.txt
2
3

Executing the script:

$ file.sh < data.txt
2
3
1
  • 1
    thats the answer also telling how to handle the inputs coming from any source, perfect Commented Dec 30, 2021 at 20:09
20

Just want to add one more way. Found it elsewhere, and is quite simple. Say I want to pass yes for all the prompts at command line for a command "execute_command", Then I would simply pipe yes to it.

yes | execute_command

This will use yes as the answer to all yes/no prompts.

1
  • 3
    This can also be customized to not just pass y but any string you like. For instance, to pass n it's enough to write yes n | execute_command
    – lupalby
    Commented Jul 22, 2022 at 7:47
12

You can also use printf to pipe the input to your script.

var=val
printf "yes\nno\nmaybe\n$var\n" | ./your_script.sh
1
  • I don't understand why, but using printf works for certain programs (such as wml), when none of the other techniques did. Commented Oct 9, 2020 at 22:50

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.