Is there a way to determine if a script is waiting on stdin and cause the command to exit if detected?

Here's an example, the command I'm executing takes a long time to run, but it will also prompt for input before starting w/o a prompt. I want to know the command is actually doing something and not just waiting.

Provided the following script called ./demo



Is there a way to detect that read is waiting on stdin? Something like

failifwaitingonstdin | ./demo

Which would immediately return as soon as the read command was detected.


Folks have suggested programs like expect and yes. After digging through yes, I see how they're able to support this style of interaction. They're constantly using fputs to write 'y' to stdout. Instead of doing this infinitely, I can simply return an error as soon as fputs returns on a write to stdout.

4 Answers 4


It would really help if you were a lot more specific about your script and/or command. But in case what you want to do is test where stdin is coming from, this example script will demonstrate that for you:

if [[ -p /dev/stdin ]]
    echo "stdin is coming from a pipe"
if [[ -t 0 ]]
    echo "stdin is coming from the terminal"
if [[ ! -t 0 && ! -p /dev/stdin ]]
    echo "stdin is redirected"
echo "$REPLY"

Example runs:

$ echo "hi" | ./demo
stdin is coming from a pipe
$ ./demo
[press ctrl-d]
stdin is coming from the terminal
$ ./demo < inputfile
stdin is redirected
$ ./demo <<< hello
stdin is redirected
$ ./demo <<EOF
stdin is redirected
  • On your second command: $ ./demo...you say you need to press Ctrl-d. I was not able to reproduce (i.e. I think you need a read somewhere in your script. To my question, how can I detect when read is waiting for input? I updated my question with more detail. Jul 1, 2010 at 3:58
  • If your program doesn't need any real input from stdin, then Gerald's suggestion of piping yes into it will make it continue since it will have that for input. Do you have the ability to modify the script? Can't you just add the test from my demo before the read in your script?: if [[ -t 0 ]]; then exit 1; done You can instead put a timeout on the read command: read -t 5 will wait for input for 5 seconds then fail if there's none. Jul 1, 2010 at 7:11
  • The demo script is not mine, so it's unmodifiable. Jul 2, 2010 at 17:03
  • As for [[ -t 0 ]] test, if you put the program in background, you can not write input to it, but the test gives true anyway.
    – jarno
    May 15, 2020 at 11:11
  • @jarno: From man bash: "If a command is followed by a & and job control is not active, the default standard input for the command is the empty file /dev/null. Otherwise, the invoked command inherits the file descriptors of the calling shell as modified by redirections." I believe this is so that if you fg (foreground via job control) the process, stdin is still attached to the process. Jun 28, 2022 at 20:11

Without knowing what you're trying to do I'd argue you should be writing the script so that you always know if it's going to ask for stdin or not. Either that or pipe something into the command that's likely to be wanting something from stdin, but that's probably not the best idea.


If you're on Linux you could use strace to see if the process is trying to read from stdin. Other platforms have similar programs (e.g. dtrace, ktrace, or truss).

You might be able to avoid the issue altogether by feeding the output of yes to the command in question.


If you are writing the scripts: bash's read builtin takes a timeout option:

read -p prompt -t 5 var # 5s timeout

If not, you can use expect, or just yes, to fake user interaction.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .