我想编写一个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
...
这有点像顶部;它会一直做某些事情,直到按下q键退出,但我想要前进到下一个步骤。
我想编写一个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
...
这有点像顶部;它会一直做某些事情,直到按下q键退出,但我想要前进到下一个步骤。
-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
kev的优秀解决方案即使在Bash 3.x中也能很好地工作。,但是它在每个循环迭代中引入了1秒的延迟(-t 1
).
在Bash 3.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
注意:以上使用 0.01
作为几乎没有超时的值,但是根据您的主机平台、终端程序以及可能存在的CPU速度/配置,可能需要更大的值 / 可能支持更小的值。如果值太小,您将看到间歇性的error setting terminal attributes: Interrupted system call
错误 - 如果有人知道原因,请告诉我们。
使用 -t 0
,根据 help read
(已加粗),其工作方式如下:
如果 TIMEOUT 是 0,则 立即返回 而不尝试读取任何数据,只有在指定的文件描述符上有输入可用时才 返回成功。
从Bash v4.4.12和5.0.11开始,不幸的是,-t 0
似乎会忽略-n
/-N
,因此只有按下ENTER键(或以ENTER键结尾的一系列按键)会导致read
指示数据可用。
如果有人知道这是一个bug还是这种行为有充分的理由,请告诉我们。
因此,只有以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
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|_set(cbreak|onechar|noecho))'
匹配的调用在lib/sh/shtty.c失败时。(删除-s
可以避免一个错误。)添加-e
以使用readline
对我来说可以避免任何错误。 - vike-t0
的信息是正确的(作为 read.def
中的特殊情况,在独立于其他选项的情况下)。虽然我发现我的 bash 5.0.7似乎支持 -t0.001
的 -n1
,但只有 -N1
的 -t0.0001
(与 -s
和 / 或 -r
无关)。奇怪的是,只有 -t0.00001
似乎受到支持,但是仅具有 -e
,只有 -t0.002233
会被支持。这些分数可能取决于本地 CPU 时间,因为 setitimer
(3) 四舍五入到“系统时钟的分辨率”(在我的 '93 manpage 中通常为10毫秒),并且在 read.def
的不同位置使用 CHECK_ALRM 宏(来自 quit.h)。 - vike