Bash: How to end infinite loop with any key presse

2019-01-07 10:54发布

I need to write an infinite loop that stops when any key is pressed.

Unfortunately this one loops only when a key is pressed.

Ideas please?

#!/bin/bash

count=0
while : ; do

    # dummy action
    echo -n "$a "
    let "a+=1"

    # detect any key  press
    read -n 1 keypress
    echo $keypress

done
echo "Thanks for using this script."
exit 0

4条回答
Deceive 欺骗
2楼-- · 2019-01-07 11:03

Here is another solution. It works for any key pressed, including space, enter, arrows, etc.

Tested in bash:

IFS=''
if [ -t 0 ]; then stty -echo -icanon raw time 0 min 0; fi
while [ -z "$key" ]; do
    read key
done
if [ -t 0 ]; then stty sane; fi
查看更多
3楼-- · 2019-01-07 11:17

Usually I don't mind breaking a bash infinite loop with a simple CTRL-C. This is the traditional way for terminating a tail -f for instance.

查看更多
Emotional °昔
4楼-- · 2019-01-07 11:27

You need to put the standard input in non-blocking mode. Here is an example that works:

#!/bin/bash

if [ -t 0 ]; then stty -echo -icanon -icrnl time 0 min 0; fi

count=0
keypress=''
while [ "x$keypress" = "x" ]; do
  let count+=1
  echo -ne $count'\r'
  keypress="`cat -v`"
done

if [ -t 0 ]; then stty sane; fi

echo "You pressed '$keypress' after $count loop iterations"
echo "Thanks for using this script."
exit 0

Edit 2014/12/09: Add the -icrnl flag to stty to properly catch the Return key, use cat -v instead of read in order to catch Space.

It is possible that cat reads more than one character if it is fed data fast enough; if not the desired behaviour, replace cat -v with dd bs=1 count=1 status=none | cat -v.

查看更多
神经病院院长
5楼-- · 2019-01-07 11:27

read has a timeout parameter -t which could be used. Do a non blocking check for input, seeing if the return status is 0 and if so break from the loop.

-t timeout

Cause read to time out and return failure if a complete line of input is not read within timeout seconds. timeout may be a decimal number with a fractional portion following the decimal point. This option is only effective if read is reading input from a terminal, pipe, or other special file; it has no effect when reading from regular files. If timeout is 0, read returns success if input is available on the specified file descriptor, failure otherwise. The exit status is greater than 128 if the timeout is exceeded.

查看更多
登录 后发表回答