Results 1 to 4 of 4
Today I ran into a strange stdin problem with bash (3.1.17). I have a script that optionally allows input from stdin like:
echo "text stream" | myscript
or can be ...
- 07-17-2007 #1Just Joined!
- Join Date
- Dec 2006
- Posts
- 5
SOLVED: bash stdin problem
Today I ran into a strange stdin problem with bash (3.1.17). I have a script that optionally allows input from stdin like:
echo "text stream" | myscript
or can be called like:
myscript
Now I also need it to be able to take input from stdin inside the script like:
read -p "Enter something: " ans
which only works when I do not have a stream piped into the script at invocation.
I think that I need to somehow disconnect stdin from external and reconnect it again to &0. I've tried a number of things like this but no luck yet.
here is a test script that exhibits the issue:
============================
#!/bin/sh
if [ "$1" == "--help" ]; then
echo "USAGE: scriptname";
echo "USAGE: echo "some string" | scriptname"
exit 0
fi
read -t 1 incoming
echo "incoming: $incoming"
read -p "Enter something: " ans
echo "You entered: $ans"
============================
test case 1:
echo "some string" | myscript
test case 2:
myscript
Test case 2 works fine. Test case 1 fails because the second read fails to wait for input.
So how to reset stdin so the second read will wait for input?
- 07-17-2007 #2
You can't "reconnect to &0". This is because your program only knows about ONE stdin: the stdin it was given by the shell. As far as it knows, there is no other stdin. You would need to tell it what that stdin is.
You can tell this by using the 'tty' command. This command tells you the filename of the terminal attached to stdin. However, if you run it when piping, you will see that it is "not a terminal".
I don't know if this is even possible, unless you somehow know the filename of the terminal in advance (for instance, supplying it as a parameter). Indeed, the whole point of abstracting stdin away from the terminal is that programs don't have to be associated with the terminal.
I'd be interested to see if you find a reliable way to do this.DISTRO=Arch
Registered Linux User #388732
- 07-17-2007 #3Just Joined!
- Join Date
- Dec 2006
- Posts
- 5
I can close the existing stdin with:
exec 0<&-
And of course this results in broken pipe errors to the shell.
Now I would need to reopen stdin as it would be in a non-piped shell but is it possible? I would need to do something like:
exec < ?????
But to what device? /dev/stdin is what you would want but it is now gone.
Ideas?
- 07-17-2007 #4Just Joined!
- Join Date
- Dec 2006
- Posts
- 5
SOLVED: bash stdin problem
Caveat: This solution works for Linux and other OS may have to adjust accordingly.
The key was finding the terminal to reattach to stdin:
term="/dev/$(ps -p$$ --no-heading | awk '{print $2}')"
Now you can do:
exec < $term
And everything works.


Reply With Quote