8

Say I've got a bash script:

#!/bin/bash

read -p "Gimme some stuff: " stuff
echo "**${stuff}**"

If the script is invoked with something piping into it, such as:

echo "Here's some stuff" | ./myscript.bash

Then the read command will read from the pipe. Even if I try to clear stdin out before I hit that read command, it will still return immediately.

Is there any way around that? If I don't have any control of the way in which my script is invoked, is there any way to force it to accept input for a read or select from the terminal? If not, are there any sneakier ways to pause the script to get input from a user other than from stdin?

glibdud
  • 203

1 Answers1

12

Yes. The terminal is always /dev/tty. All that is necessary is to have read get its input from the terminal rather than stdin:

#!/bin/bash

read -p "Gimme some stuff: " stuff </dev/tty
echo "**${stuff}**"

In operation, this looks like:

$ echo asdfdsaf | read.sh
Gimme some stuff: 123
**123**

A slightly more complex way of doing the same thing

Here we open /dev/tty as file descriptor 3. The option -u 3 tells read to use file descriptor 3:

exec 3<>/dev/tty
read -u 3 -p "Gimme some stuff: " stuff
echo "**${stuff}**"
John1024
  • 17,343