2015-09-06 39 views
0

嗨即时尝试暂停进程的执行,以便用户不能进行多个条目,直到5秒过去。我尝试使用睡眠,但睡眠只是停下来,然后执行用户在进程睡着时运行的所有输入,我不希望在程序睡眠时有任何输入读取。Bash Unix:我怎样才能暂停进程而不使用睡眠命令

的我想要什么

例如:一个聊天机器人 输入1:喜 输出:“从程序回复” 输入2(5秒前是上升):“什么新的” -NO输出 - 输入 3( 5秒过去了):“你好吗” 输出:即时通讯罚款。什么睡眠命令不

例如: 输入1“喜” 输出“哎” 输入2(5秒前):“什么新的” - 没有输出 - 等待 输入3:“你怎么样“ 输出:‘没有多少是新的’ 输出:‘我没事’

+0

使用while循环并计算时间。 –

+1

请查看[editing-help](http://stackoverflow.com/editing-help)。 – Cyrus

+0

这不是一件容易的事:这里不是你的程序,而是环境的工作方式:它缓冲输入,直到你的程序再次接受它为止。您可以尝试从输入中分离临时文件,但最简单的方法是实际读取并转储所有输入5秒钟。 – arkascha

回答

1

你可以阅读和5秒后扔掉用户的输入可达

# 1. 
read -p "prompt 1: " first_thing 

sleep 4 

# this reads and ignores whatever the user has typed during the sleep 
while read -t 1 _garbage; do :; done 

# 2. 
read -p "prompt 2: " next_thing 

read小号-t 1运如果没有什么可读的话,则是一秒超时。

测试

  1. 与输入

    $ read -p "prompt 1: " first_thing; sleep 4; while read -t 1 _garbage; do :;done ; read -p "prompt 2: " next_thing 
    prompt 1: foo 
    bar 
    baz 
    prompt 2: qux 
    $ echo $first_thing $next_thing 
    foo qux 
    
  2. 第二读之前没有 “额外” 输入 - 过程中不 “挂” 在等待输入

    $ read -p "prompt 1: " first_thing; sleep 4; while read -t 1 _garbage; do :;done ; read -p "prompt 2: " next_thing 
    prompt 1: hello 
    prompt 2: world 
    $ echo $first_thing $next_thing 
    hello world 
    
1

这绝非易事,而你需要更具体地说明您希望脚本如何响应键盘输入。

没有办法“锁定”键盘;用户可以继续按照他们认为合适的方式打孔。如果您是内容的钥匙要呼应,但你要输入被忽略,你可以这样做以下:

# Beware! Read the entire answer; don't just use this command 
timeout 5 bash -c 'while :;do read -s -d ""; done' 

timeout实用程序运行一个命令,杀死它时,指定的秒数已经过去;指定的数字可能是小数部分。围绕read命令的循环是必需的,因为read会在按下Enter键后立即终止; while :; do是“永远循环”的标准成语。

timeout命令是Gnu coreutils的一部分。如果你没有它,也许是因为你正在使用BSD衍生产品,你可能会找到其他选择。有一个FreeBSD命令,可能在其他BSD上可用,包括Mac OS X,名为timelimit;我相信正确的调用是将timeout 5替换为timelimit -t 5 -s9,但我没有任何简单的测试方法。

您需要让read命令立即实际读取输入,而不是等到按下Enter键。否则,在终止read之后,键入的输入仍然可用于下一个命令。

有几种方法可以做到这一点。一种是使用-n 1标志使read在每个字符后返回;另一种方法是使用-d ""将输入字符的末尾设置为NUL,这会将读取置于一次一个字符模式。

此外,您可能想要抑制在读取循环中按下的键的回显。您可以通过将-s标志添加到read命令来做到这一点,但是当read命令被中断时,将会产生副作用,使终端处于“无回声”模式。 [注1]

不幸的是,您可能会发现终端设置已被永久更改,因为readtimeout命令终止时,它没有机会恢复终端设置。所以你最终会得到一个终端,它不回应,不处理退格和其他行编辑命令,并且不遵守Ctrl-D等问题。

为避免此问题,您需要保存并恢复终端设置。你可以做到这一点的stty命令,如下所示:

# Save the terminal settings 
saved=$(stty -g) 
# Ignore input for 5 seconds, suppressing echo 
timeout 5 bash -c 'while :;do read -s -d ""; done' 
# Restore the terminal settings 
stty "$saved" 

  1. 如果不抑制回声,你会发现你的输入提示可以在同一行上出现的忽视输入。您可避免通过输出一个“回车/擦除结束行的”前提示控制序列:

    tput cr; tput el; read -p "Give me some input: " 
    
0

@glenn的答案是一个很好的答案!
也许你不知道前面你要睡多久(你打电话 一些其他功能)。 当你只想刷新输入队列时,你可以尝试类似的方法:

echo "What is your name?" 
read name 
echo "Please be quiet for 5 seconds" 
sleep 5 

smalltime=0.000001 
read -t ${smalltime} -s garbage 
while [ -n "${garbage}" ]; do 
    echo "Flushing $garbage" 
    read -t ${smalltime} -s garbage 
done 

echo "Hello ${name}, please say something else" 
read y 
echo "You said $y"