在没有用户输入30秒后终止脚本



我正在尝试创建一个简单的Bash脚本,该脚本在等待用户输入10秒后终止。如果用户输入了一些内容,计时器将重置,10秒规则将再次适用。我使用陷阱来确保我的程序可以退出的唯一两种方式是:

  1. 我输入";停止">
  2. 用户10秒未输入

我试过使用类似的东西

{
sleep 10s
kill $$
} &

但按下Ctrl-C后,它不会在10秒后停止程序。它无限期地持续着。

您可以使用read的超时选项。但请注意,只有当用户按下回车键完成输入时,这不会重置。

read -t 10 userinput || exit 1

如果您使用的是set -e,则可以提交|| exit 1

read可能由于其他原因而失败,因此您可以专门测试超时。超时错误代码大于128。

read -t 10 userinput || { (($?>128)) && exit 1; }

if ! read -t 10 userinput && (($? > 128)); then
echo 'you timed out' >&2
exit 1
fi

如果read失败,您可能无论如何都要退出。但是测试超时错误代码可以打印相关的错误消息。

read有一个超时参数,您可以使用:

read -t 30 answer

POSIX TTY行规程提供了这样一个功能:一个可配置的计时器,每当输入到达时就会重置,并在read()操作到期时终止。当TTY处于原始模式(如串行线(时,此计时器通常用于生成更大的读数。

在这个概念验证解决方案中有一些棘手的问题。它处理Ctrl-Z在读取期间暂停工作的要求,并重置计时器:

#!/bin/sh
# save the TTY settings, to restore later
# this should ideally be done in an exit/interrupt trap.
saved_tty=$(stty -g)
# initialize some variables
resumed=            # flag indicating Ctrl-Z resume
biginput=           # total input collected
littleinput=        # input from one read operation
# function to set a special TTY mode, and set the resumed flag
set_tty_mode()
{
# turn of canonical mode; set up 10 second timer (100 x 0.1s)
# min 0 means read a minimum of 0 bytes, allowing timer to work
stty -icanon min 0 time 100 
# setting this flag plays a role when this function is called
# as the SIGCONT interrupt handler.
resumed=y
}
# switch to above TTY mode
set_tty_mode
# when the SIGCONT signal goes off, indicating we resumed from Ctrl-Z
# suspend, call set_tty_mode. This is because when we are suspended,
# the shell, e.g. Bash, messes with the TTY settings.
trap set_tty_mode CONT
# no we loop, reading into the littleinput variable.
while true ; do
resumed=                          # clear the flag
read littleinput                  # read input
biginput="$biginput$littleinput"  # accumulate
[ $resumed ] || break             # terminate loop, unless SIGCONT happened
done
printf "read: [%s]n" "$biginput"
stty $saved_tty

最新更新