Bash 脚本侦听按键以继续前进

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9731281/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:47:48  来源:igfitidea点击:

Bash script listen for key press to move on

bashshell

提问by Cripto

So, I want to write a bash script that are a sequence of steps and ill identify it as "task#". However, each step is only completed and can run as long as the user wants.

所以,我想编写一个 bash 脚本,它是一系列步骤,并将其标识为“任务#”。但是,每个步骤都只是完成,并且可以根据用户的需要运行。

Do task1
if keypressed stop task1 and move on #this is the part I need help with. There can be up to 10 of these move on steps. 
Do task2
...

kina like top; it keeps doing stuff until you hit q to quite, however, i want to move on to the next thing

基那像顶部; 它一直在做一些事情,直到你按 q 完全,但是,我想继续做下一件事

回答by kev

you can use readbuiltin command with option -tand -n

您可以使用read带有选项-t和的内置命令-n

while :
do
    # TASK 1
    date
    read -t 1 -n 1 key

    if [[ $key = q ]]
    then
        break
    fi
done

# TASK 2
date +%s

回答by mklement0

kev's great solutionworks well even in Bash 3.x., but it introduces a 1-second delay(-t 1) in every loop iteration.

kev 的出色解决方案即使在 Bash 3.x 中也能很好地工作。,但它会在每次循环迭代中引入1 秒延迟( -t 1)。

In Bash 3.x, the lowest supported value for -t(timeout) is 1(second), unfortunately.

不幸的-t1Bash 3.x 中,(timeout)支持的最低值(second)

Bash 4.x supports 0and fractionalvalues, however:

Bash 4.x 支持0数值,但是:

A solution that supports an arbitrary keysuch as qrequires a nonzero-tvalue, but you can specify a value very close to 0to minimize the delay:

支持任意键(例如q需要非零-t值)的解决方案,但您可以指定一个非常接近的值0以最小化延迟

#!/bin/bash
# !! BASH 4.x+ ONLY

while :; do

  # Loop command
  date

  # Check for 'q' keypress *waiting very briefly*  and exit the loop, if found.
  read -t 0.01 -r -s -N 1 && [[ $REPLY == 'q' ]] && break

done

# Post-loop command
date +%s

Caveat: The above uses 0.01as the almost-no-timeout value, but, depending on your host platform, terminal program and possibly CPU speed/configuration, a larger value may be required / a smaller value may be supported. If the value is too small, you'll see intermittent error setting terminal attributes: Interrupted system callerrors- if anyone knows why, do tell us.

警告:以上0.01用作几乎无超时值,但是,根据您的主机平台、终端程序和可能的 CPU 速度/配置,可能需要更大的值/可能支持更小的值。如果值太小,您会看到间歇性error setting terminal attributes: Interrupted system call错误- 如果有人知道原因,请告诉我们。



Tip of the hat to jarnofor his help with the following:

在帽子的提示亚诺他与以下帮助:

Using -t 0, works as follows, according to help read(emphasis added):

使用-t 0, 工作如下,根据help read(强调):

If TIMEOUT is 0, read returns immediately, without trying to read any data, returning success only if input is availableon the specified file descriptor.

如果 TIMEOUT 为 0,则 read立即返回,不尝试读取任何数据,仅当指定文件描述符上的输入可用时才返回成功

As of Bash v4.4.12 and 5.0.11, unfortunately, -t 0seems to ignore-n/ -N, so that only an ENTERkeypress (or a sequence of keypresses ending inENTER) causes readto indicate that data is available.
If anyone knows whether this is a bugor whether there's a good reason for this behavior, do let us know.

不幸的是,从 Bash v4.4.12 和 5.0.11 开始-t 0似乎忽略了-n/ -N,因此只有ENTER按键(或以结尾的按键序列ENTER)导致read表明数据可用
如果有人知道这是一个错误还是这种行为是否有充分的理由,请告诉我们。

Therefore, only with ENTERas the quit key is a -t 0solution currently possible:

因此,只有使用ENTER退出键才是-t 0目前可能的解决方案

#!/bin/bash
# !! BASH 4.x+ ONLY

while :; do

  # Loop command
  date

  # Check for ENTER keypress and, after clearing the input buffer
  # with a dummy `read`, exit the loop.
  read -t 0 -r -N 1 && { read -r; break; }

done

# Post-loop command
date +%s