【问题标题】:Bash script listen for key press to move onBash 脚本监听按键以继续
【发布时间】:2012-04-01 15:25:41
【问题描述】:

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

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 喜欢上衣;它一直在做一些事情,直到你把 q 打到相当为止,但是,我想继续下一件事情

【问题讨论】:

标签: bash shell


【解决方案1】:

kev's great solution 即使在 Bash 3.x 中也能正常工作。,但它会在每次循环迭代中引入 1 秒延迟 (-t 1) .

不幸的是,在 Bash 3.x 中,-t(超时)支持的最低值是1(秒)

Bash 4.x 支持 0fractional,但是:

支持任意键(例如q)的解决方案需要一个非零-t 值,但您可以指定一个非常接近@ 的值987654330@ 尽量减少延迟

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

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


jarno 致谢,感谢他在以下方面的帮助:

使用-t 0,根据help read(已添加重点)如下工作:

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

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

因此,只有使用 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

【讨论】:

  • getting search hit here for and researching error of setting terminal attributes from bash -o monitor -c 'read -t1 -n1 -s -pp: r &'(NB -o monitor for &),我发现错误来自内置/当grep -EHn 'tt(setattr|_set(cbreak|onechar|noecho))'lib/sh/shtty.c 中匹配的某些调用失败时,read.def 在 builtins/common.c 中调用 sh_ttyerror(1)。 (删除-s 可以防止出现一个错误。)添加-e 以使用readline 可以防止出现任何错误。
  • 谢谢,@vike。根据您的发现,有没有办法使上述工作与-t 0 一起工作?
  • 不,-t0 上的信息检出(作为 read.def 中的特殊情况,独立于其他选项)。虽然,我确实发现我的 bash 5.0.7 似乎只支持 -t0.001-n1,但 -t0.0001 只支持 -N1(独立于 -s 和/或 -r )。奇怪的是,-t0.00001 似乎只支持 opt,但 -e 只有 -t0.002233 支持。这些分数可能取决于本地 cpu 时间,因为 setitimer(3) 舍入到“系统时钟分辨率”(在我的 '93 手册页中为“通常为 10 毫秒”),使用 ITIMER_REAL 和 CHECK_ALRM 宏(从退出。 h) 在 read.def 中的不同位置使用。
  • 感谢您深入挖掘,@vike。鉴于您已经完成了多少研究,我鼓励您提交一份详细的错误报告以回复 -t 0(例如通过 bashbug 脚本)。
【解决方案2】:

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

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

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

# TASK 2
date +%s

【讨论】:

  • @jarno:感谢您的更正和指点。我已经删除了我原来的评论,并决定深入挖掘我自己的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-23
  • 1970-01-01
  • 2010-10-13
  • 2012-06-26
  • 1970-01-01
  • 2012-08-12
  • 2015-12-17
相关资源
最近更新 更多