Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have to write a script for this program. choose a random letter within a-z. Ask the user to guess the letter, match it with the chosen letter. If matched, display "correct", else prompt if the guessed letter is above or below the chosen letter. Can someone demonstrate with examples of how I might do this in the shell?

share|improve this question

closed as too broad by Patrick, Matteo, jasonwryan, Anthon, Braiam May 26 at 13:26

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.If this question can be reworded to fit the rules in the help center, please edit the question.

    
Shell-script means KSH? (BA)SH? (T)CSH? Builtins only? Standard BSD-userland? –  yeti May 26 at 6:25
    
stack overflow is likely a better place to ask this question. –  spuder May 26 at 6:26
    
@yeti anyone among sh or bash –  user3331420 May 26 at 6:34
5  
Is this a homework problem? –  mdpc May 26 at 6:56
5  
What have you tried so far? What are you having problems with? We're happy to answer specific questions, but what you're asking for is someone to write a script for you. We're not here to do your work for you. –  Patrick May 26 at 6:56
add comment

3 Answers 3

BASH

BASH is nice for this job because BASH can generate the alphabet easily by using {a..z} and BASH can input a single char without needing to hit ENTER

$ cat guesschar.bash 
c=$(echo {a..z} | tr -d ' ')
x=${c:$((RANDOM%26+1)):1}
while read -n1 -p'guess the char: ' ; do
        echo
        if [[ $REPLY < $x ]] ; then echo too low...
        elif [[ $REPLY > $x ]] ; then echo too high...
        else break
        fi
done
echo $x ... 'hit!'
$ bash guesschar.bash 
guess the char: m
too high...
guess the char: f
too low...
guess the char: j
too low...
guess the char: k
k ... hit!
share|improve this answer
    
thanks a lot...i can use the same code in sh also r wat?? –  user3331420 May 26 at 8:48
    
No. In sh this will be a much longer program. Compare the documentation. I think sh will not have the range expression {a..z}, not the RANDOM variable and not reading single keystrokes via read -n1. –  yeti May 26 at 9:06
    
No, this wouldn't be a much longer program in plain shell - I'm pretty sure I could do this shorter in shell - but both programs would be ASCII locale specific. If you wanted to do this and handle any alphabet... well, that would be a much longer program. –  mikeserv May 26 at 11:46
add comment
rand=$(tr -dc '[:lower:]' </dev/urandom | 
    dd bs=1 count=1 status=none)
until [ "$in" = "$rand" ] && echo "correct" ; do
    in=$(stty raw 
    dd bs=1 count=1 status=none </dev/tty 
    stty sane )
    echo
done

I think the above does what you need.

share|improve this answer
    
May I suggest head -c 1 instead of dd... for handling ASCII char one by one?. Just a suggestion though, but it's a bit more readable –  lgeorget May 26 at 12:22
    
@igeorget - good suggestion, but I think just the echo handles that. And dd is portable - even if /dev/urandom probably isn't. –  mikeserv May 26 at 12:23
    
hmmm... tested replacing occurrences of dd bs=1 count=1 status=none by head -c1, I got exactly the same behaviour. Well, anyway, that's just a matter of style, nothing important :) –  lgeorget May 26 at 12:31
    
What behavior? You mean the characters stringing together? That's stty raw doing that - that's why I added the echo. –  mikeserv May 26 at 12:32
1  
You get my +1 for usage of /dev/urandom : shell has many tools for read/write operations and there is a PRNG accessible through the filesystem so no need to generate the random bytes in the code –  lgeorget May 26 at 12:33
show 5 more comments

If you want a portable way, you can try:

perl -e 'print ("a".."z")[rand 26]'
share|improve this answer
    
There's no need for the map here; you could just do perl -e 'print(("a".."z")[rand 26])'. –  Tom Fenech May 26 at 11:20
    
@TomFenech: Thanks, updated my answer! –  Gnouc May 26 at 11:37
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.