Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash脚本侦听按键以继续_Bash_Shell - Fatal编程技术网

Bash脚本侦听按键以继续

Bash脚本侦听按键以继续,bash,shell,Bash,Shell,因此,我想编写一个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 ... 基纳样顶;它一直在做一些事情,直到你点击q到quite,但是,我想继续下一

因此,我想编写一个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
...

基纳样顶;它一直在做一些事情,直到你点击q到quite,但是,我想继续下一件事

你可以使用
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
即使在Bash 3.x中也能很好地工作。,但它在每次循环迭代中引入1秒延迟(
-t1

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

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

支持任意键的解决方案
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
#!/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
警告:上面使用
0.01
作为几乎没有超时值,但是,根据主机平台、终端程序和可能的CPU速度/配置,可能需要较大的值/可能支持较小的值。如果该值太小,您将看到间歇
错误设置终端属性:中断系统调用
错误-如果有人知道原因,请告诉我们


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

使用
-t0
,根据
帮助阅读(添加了重点),其工作原理如下:

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

从Bash v4.4.12和5.0.11开始,不幸的是,
-t0
似乎忽略了
-n
/
-n
,因此只有ENTER键(或以ENTER结尾的一系列按键)导致
读取
指示数据可用
如果有人知道这是否是一个bug,或者这种行为是否有充分的理由,一定要让我们知道

因此,仅使用ENTER键作为退出键是当前可能的
-t0
解决方案

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

@贾诺:我感谢你的纠正和指点。我已经删除了我原来的评论,并决定在我自己的答案中进行更深入的挖掘。while loop subset:Get search hit here for并研究
bash-o monitor-c'read-t1-n1-s-pp:r&
(NB
-o monitor
for
&
)中设置终端属性的错误,我发现错误来自builtins/read.def在builtins/common.c中调用sh_ttyerror(1),当一些与
grep-EHn'tt(setattr | u set(cbreak | onechar | noecho))匹配的调用失败时,
。(删除
-s
可防止出现一个错误。)为使用
readline
添加
-e
可防止我出现任何错误。谢谢,@vike。根据您的调查结果,是否有办法使上述内容在
-t0
中起作用?否,
-t0
上的信息将被检出(作为read.def中的特例,独立于其他选项)。尽管如此,我还是发现我的bash5.0.7似乎只支持
-n1
-t0.001
,而
-t0.0001
只支持
-n1
(独立于
-s
和/或
-r
)。奇怪的是,
-t0.00001
似乎只支持opt,但只有
-e
才支持
-t0.002233
。这些分数可能取决于本地cpu时间,因为ITIMER_REAL调用了
setitimer
(3)轮到“系统时钟分辨率”(在我的'93手册页中通常为10毫秒),并且在read.def的不同位置使用了CHECK_ALRM宏(来自quit.h)。感谢深入挖掘,@vike。考虑到您已经做了大量的研究,我鼓励您提交一份关于
-t0
的详细bug报告(例如通过
bashbug
脚本)。