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! :)

Comments

Ivo van der Wijk

In case anyone's looking for the answer:
$ x="
"
$ if [ "$x" = $'\n' ]; then echo "newline"; fi
newline

Anonymous

#!/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

Your email will never ever be published.

Previous:
New domain name October 20, 2006 This site
Next:
Sending HTML emails in Zope October 26, 2006 Zope
Related by category:
How to find which git SHA it was when you merged in the default branch February 26, 2026 Linux
hylite as an executable October 15, 2025 Linux
Elasticsearch memory usage December 11, 2025 Linux
How to count the number of non-blank lines with Bash September 3, 2025 Linux
Related by keyword:
gg shell completion August 13, 2025 Linux, JavaScript, Bun, macOS
Find the source of an alias in bash September 29, 2025 Linux, Bash, macOS
set -ex - The most useful bash trick of the year August 31, 2014 Linux
Introducing hylite - a Node code-syntax-to-HTML highlighter written in Bun October 3, 2023 Node, JavaScript, Bun