Crosstips.org

My fun Crossword solver project. Crosstips.org & Krysstips.se

Kung Fu

Fujian White Crane Kung Fu

Fry-IT

Fry-IT is the company I work for

Photos

Photoalbum, both old and new.

Zope

What I have and am doing with Zope

Receptsamlingen

In Swedish only. About my "Collection of Recipes" website.

Contact me

My contact details and how to contact me.

 

KungFuPeople.com
Do you train Kung Fu?
Or know someone who does?
Then check out KungFuPeople.com


Mobile version of this page Mobile version of this page


 

Catching a carriage return in bash


23rd of October 2006

I'm not a bash expert. Now I need some help with some bash syntax.

I copied a function called get_key which takes a 1 character length string from the stty input and assigns it to a variable. It's nifty because I can prompt something like this:

 Select task:
 1 - Task XYZ
 2 - Task F19
 3 - Task 123
 q - quit

So far so good. What I now want to do is to introduce a possible default. If you just hit enter the variable becomes a carriage return I think. If that's the case I have some other stuff that will kick in and find choose a default value. Here's the code:

 echo "Enter 1, 2, 3, q or just hit Enter";
 get_key Q; # assigns one character to variable Q
 if [ "$Q" = "\n" ]; then
    echo "Q was blank!";
 else
    echo "|$Q|"; # for debugging what Q is
 fi

The problem is that when I run this it never prints "Q was blank!". Here's the output when I just hit the Enter key when it runs:

 Enter 1, 2, 3, q or just hit Enter

 |
 |

Is the syntax not right? How do I compare if a variable is just a linkbreak/carriage return?

UPDATE

It's quite clear that my get_key function must do something strange. This little script will print "is" when you run it:

 Q="\n";
 if [ "$Q" = "\n" ]; then
    echo "is";
 fi

The get_key function is defined like this:

 get_key()
{
    [ -t 0 ] && {  ## Check whether input is coming from a terminal
        [ -z "$_STTY" ] && {
            _STTY=$(stty -g)  ## Store the current settings for later restoration
        }

        ## By default, the minimum number of keys that needs to be entered is 1
        ## This can be changed by setting the dd_min variable
        ## If the TMOUT variable is set greater than 0, the time-out is set to
        ## $TMOUT seconds
        if [ ${TMOUT:--1} -ge 0 ]
        then
          _TMOUT=$TMOUT
          stty -echo -icanon time $(( $_TMOUT * 10 )) min ${dd_min:-1}
        else
          stty -echo -icanon min ${dd_min:-1}
        fi
    }

    ## Read a key from the keyboard, using dd with a block size (bs) of 1.
    ## A period is appended, or command substitution will swallow a newline
    _KEY=$(dd bs=1 count=1 2>/dev/null; echo .)
    _KEY=${_KEY%?}  ## Remove the period

    ## If a variable has been given on the command line, assign the result to it
    [ -n "$1" ] &&
            ## quoting
            case $_KEY in
                 "'") eval "$1=\"'\"" ;;
                 *) eval "$1='$_KEY'" ;;
            esac
    [ -t 0 ] && stty "$_STTY"  ## reset terminal
    [ -n "$_KEY" ]  ## Succeed if a key has been entered (not timed out)
 }

UPDATE2

Thank you Ivo! That solved the problem! :)



Comment

Ivo van der Wijk - 24th October 2006  [«« Reply to this]
In case anyone's looking for the answer:
$ x="
"
$ if [ "$x" = $'\n' ]; then echo "newline"; fi
newline
Anonymous - 18th August 2008  [«« Reply to this]
#!/bin/bash

m() {
cat << EOP

Select task:
1 - Task XYZ
2 - Task F19
3 - Task 123
q - quit

EOP
}
k="1"
until [[ $k == [qQ] ]]; do
m
echo "enter 1, 2, 3, q or just hit Enter"
read -n 1 k
case $k in
1) echo "doing task XYZ" ;;
2) echo "doing task F19" ;;
3) echo "doing task 123" ;;
'') echo "Q was blank";;
q) echo "quitting now" && exit 0 ;;
*) echo "invalid key" ;;
esac
done
 
Name:
Email:
hide my email address.

Your email address will be encoded to prevent email-extraction spiders from reading it so you won't get spammed if you decide to show your email address.