5

I am making a script that is taking input via a pipe (stdin), as in (other_command | my_script). However, I need to pause the script and wait for the user to press enter, after I have read the whole stdin.

Here is an example-script.

#!/bin/bash

if [[ -t 0 ]]; then
  echo "No stdin"
else
  echo "Got stdin"
  while read input; do
    echo $input
  done
fi

echo "Press enter to exit"
read

And it works like this;

$ echo text | ./script
Got stdin
text
Press enter to exit
$

It jumps over my final read.

However;

$ ./script
No stdin
Press enter to exit
stops here
$

How can I get the read to work after I have read from stdin? And is there a solution that would work on both Linux and OSX?

1 Answer 1

6

You want to read from the user. If stdin is not the user, you have to read from somewhere else. The typical choice is the current terminal (here the terminal connected to stderr, assuming there is one).

read -p "Press enter" < "$(tty 0>&2)"

By default tty finds the name of the tty on stdin, which obviously won't work when stdin is a pipe. Therefore, we redirect to make it look at stderr instead.

Sign up to request clarification or add additional context in comments.

5 Comments

Good points, however, tty sais not a tty if runned like this. /dev/ttys006 otherwise. Hence, read < "/dev/ttys006" works, but is not feasible.
Are you sure you didn't miss a bit of the command somewhere? "$(tty)" simply says **execute tty and provide the results quoted. tty would return something like /dev/ttys006 (depending on the system/terminal). So "$(tty)" should do exactly "/dev/ttys006" Execute the following in your terminal to check ( mytty="$(tty)"; echo "tty: $mytty" )
echo "tty" > test; sh test; echo string | sh test shows one line with /dev/ttys006 and one with not a tty. Happening on both my OSX and Linux test.
Works like a charm after adding 0>&2 as you edited. :)
Do you mind writing a quick sum-up of exactly why 0>&2 worked? It will make the answer more complete.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.