# Bash INKEY$ function...

**URL:** <https://community.unix.com/t/bash-inkey-function/326196>\
**Category:** UNIX for Dummies Questions & Answers\
**Created:** [March 25, 2013, 5:51pm UTC](https://community.unix.com/t/bash-inkey-function/326196 "2013-03-25T17:51:01Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![wisecracker](https://community.unix.com/user_avatar/community.unix.com/wisecracker/32/2800_2.png) [@wisecracker](https://community.unix.com/u/wisecracker)\
**Post date:** [March 25, 2013, 5:51pm UTC](https://community.unix.com/t/bash-inkey-function/326196/1 "2013-03-25T17:51:01Z")

</div>

This is probably common knowledge to the professionals but not so much for amateurs like  
myself.

This is a code snippet for the equivalent of BASIC's...

LET char$=INKEY$

As the timeout parameter cannot be less than 1 second then this is the only limitation...

It is a single line function which has a variable "char"...

Read the code for more information...

Issued as Public Domain...

```nohighlight
#!/bin/bash

# An INKEY$ function for bash!
inkey() { char="" ; read -p "" -n1 -s -t1 char ; }
# Similar to BASIC's LET char$=INKEY$

# Do you remember INKEY$ in BASIC programming?
# Example:-
#
# PRINT "Some prompt:- "
# some_label:
# LET char$=INKEY$
# IF char$="<some_character>" THEN <do_something>
# IF char$="" THEN <do_something_else>
# GOTO some_label

# This is just a test piece only...
while true
do
	printf "Some prompt:- "
	# This is LET char$=INKEY$...
	inkey
	printf "Key pressed:- '$char'...\n"
	if ["$char" == "q"]
	then
		printf "Quitting... \n"
		break
	fi
	if ["$char" == ""]
	then
		printf "Timeout works OK...\n"
	fi
	if ["$char" == "b"]
	then
		printf "Barry Walker...\n"
	fi
done

```

---

<div class="post-metadata">

**Author:** ![Corona688](https://community.unix.com/letter_avatar/corona688/32/5_5575768a8748004e209b776fc1b2916d.png) [@Corona688](https://community.unix.com/u/Corona688)\
**Post date:** [March 25, 2013, 6:15pm UTC](https://community.unix.com/t/bash-inkey-function/326196/2 "2013-03-25T18:15:07Z")

</div>

What read -n 1 is doing here is probably something like `stty -icanon min 1 ; get_character ; reset`

...since it's not BASH that's preventing you from reading one at a time, but the terminal itself. Usually it's in "canon" mode, or line-by-line.

---

<div class="post-metadata">

**Author:** ![wisecracker](https://community.unix.com/user_avatar/community.unix.com/wisecracker/32/2800_2.png) [@wisecracker](https://community.unix.com/u/wisecracker)\
**Post date:** [March 26, 2013, 3:46am UTC](https://community.unix.com/t/bash-inkey-function/326196/3 "2013-03-26T03:46:29Z")

</div>

Hi Corona688...

Thanks for the info...  
One day I will become a coder... ;o)

I have used a derivative of it in the next stage of the AudioScope as a pseudo vertical shift control, so I thought I would let other people like me have it...

---

<div class="post-metadata">

**Author:** ![rbatte1](https://community.unix.com/letter_avatar/rbatte1/32/5_5575768a8748004e209b776fc1b2916d.png) [@rbatte1](https://community.unix.com/u/rbatte1)\
**Post date:** [March 26, 2013, 7:21am UTC](https://community.unix.com/t/bash-inkey-function/326196/4 "2013-03-26T07:21:10Z")

</div>

What's wrong with

```nohighlight
stty raw -echo
inkey=`dd bs=1 count=1 2>/dev/null`
stty -raw echo

```

...that someone excellently posted a while back. This can be tweaked for particular shell, but doesn't rely on the shell's inbuilt functions and is less susceptible to the variations across OS flavours.

Bring back the ZX-Spectrum (Ran out of colours!)

Robin

---

<div class="post-metadata">

**Author:** ![Corona688](https://community.unix.com/letter_avatar/corona688/32/5_5575768a8748004e209b776fc1b2916d.png) [@Corona688](https://community.unix.com/u/Corona688)\
**Post date:** [March 26, 2013, 11:44am UTC](https://community.unix.com/t/bash-inkey-function/326196/5 "2013-03-26T11:44:46Z")

</div>

For one thing, it assumes that a keystroke is one character(frequently untrue).

For another, it runs stty twice per keystroke... I'd be tempted to leave the terminal as is instead of changing it that often, save you a lot of CPU time.

This should work work:

```nohighlight
stty -icanon min 0 time 1

key=`dd count=1 2>/dev/null`

...

```

It should be able to read entire keystrokes at once.

---

<div class="post-metadata">

**Author:** ![wisecracker](https://community.unix.com/user_avatar/community.unix.com/wisecracker/32/2800_2.png) [@wisecracker](https://community.unix.com/u/wisecracker)\
**Post date:** [March 26, 2013, 1:49pm UTC](https://community.unix.com/t/bash-inkey-function/326196/6 "2013-03-26T13:49:02Z")

</div>

Hi rbatte1...

> [@rbatte1](#):
>
> What's wrong with
> 
> ```plaintext
> stty raw -echo
> inkey=`dd bs=1 count=1 2>/dev/null`
> stty -raw echo
> 
> ```

It is NOT a callable one liner function?

;o)

Thanks to Corona688 and his knowledge...

Here we go a single line function:-

```plaintext
#!/bin/bash

inkey() { char="" ; stty -icanon min 0 time 1 ; char=`dd count=1 2>/dev/null` ; }

while true
do
	printf "Some prompt:- "
	# This is LET char$=INKEY$...
	inkey
	printf "Key pressed:- '$char'...\n"
	if ["$char" == "q"]
	then
		printf "Quitting... \n"
		break
	fi
	if ["$char" == ""]
	then
		printf "Timeout works OK...\n"
	fi
	if ["$char" == "b"]
	then
		printf "Barry Walker...\n"
	fi
done

```

Bazza...
