views:

106

answers:

2

Hi All,

I use the below code to assign a given by the user character to variable G:

read G

However in order to move forward with executing of my script I need to press enter button. Is it possible to set the read command somehow that it show process forward to the next line immediately after it receive the one letter from stdin?

+1  A: 

If you're using Bash:

read -n1 G

Your system is configured to use dash by default and dash doesn't support this feature, so you also need to change the first line of your script to specify that you wish you use bash:

#!/bin/bash
Mark Byers
This doesn't work, it doesn't wait for the input anymore just allows to execute my loop until the end.
goe
That's probably because you have errors elsewhere in your script. Try typing it in a new empty script and you'll find that it works just fine.
Mark Byers
So you're saying that read -n1 G should pause the script until it receives on character from stdin and then continue executing without waiting for enter to be clicked?
goe
BTW: the clean testing script I wrote as you suggested gives me this message: "read: 4: Illegal option -n" can that be because I'm writing in "#!/bin/sh"?
goe
I tested this using bash. What shell are you using?
Mark Byers
It's not bash, it's the most basic one "#!/bin/sh"
goe
It's unlikely that you are using the Bourne shell. It's probably another shell (maybe ash) that is either renamed or linked from /bin/sh. Try ls -l /bin/*sh and post the output here.
Mark Byers
-rwxr-xr-x 1 root root 702160 2008-05-12 14:33 /bin/bashlrwxrwxrwx 1 root root 4 2008-08-19 08:24 /bin/sh -> dash
goe
You're using the Debian Almquist shell (http://en.wikipedia.org/wiki/Debian_Almquist_shell). It has very few features - it is not even POSIX compliant. You can see here http://git.kernel.org/?p=utils/dash/dash.git;a=blob;f=src/miscbltin.c;h=046f2f29063eb8e0d631e830f63b3214dd9c1401;hb=HEAD that only -p and -r are supported. So unfortunately "read -n" is one of the features it is missing. You can't do what you're asking for unless you change your shell. Sorry.
Mark Byers
Oops, I just read the Wikipedia page - it is apparently POSIX compliant. :) But still it doesn't have the feature you need.
Mark Byers
I just noticed - you have bash installed too. Why not just used that instead?
Mark Byers
I have updated my answer - I think it should solve your problem now.
Mark Byers
Have you tried this solution? Does it work for you?
Mark Byers
A: 

I thought dd might be able to do this, so I tried it out and didn't get anywhere. However, Google found this for me and I adapted it here:

readOne () {
    local oldstty
    oldstty=$(stty -g)
    stty -icanon -echo min 1 time 0
    dd bs=1 count=1 2>/dev/null
    stty "$oldstty"
}

Define this function once at the beginning of your script, then you can use it like this:

char=$(readOne)    # get the character
echo $char         # print the character (or you can do something else with it)
Dennis Williamson