![bash:循环内非阻塞读取](https://linux22.com/image/60197/bash%EF%BC%9A%E5%BE%AA%E7%8E%AF%E5%86%85%E9%9D%9E%E9%98%BB%E5%A1%9E%E8%AF%BB%E5%8F%96.png)
我有一个以下的小 bash 脚本
var=a
while true :
do
echo $var
sleep 0.5
read -n 1 -s var
done
它只是打印用户输入的字符并等待下一次输入。我想做的实际上是不阻塞读取,即每 0.5 秒打印用户输入的最后一个字符。当用户按下某个键时,它应该继续无限地打印新键,直到按下下一个键,依此类推。
有什么建议么?
答案1
从help read
:
-t timeout time out and return failure if a complete line of input is
not read within TIMEOUT seconds. The value of the TMOUT
variable is the default timeout. TIMEOUT may be a
fractional number. If TIMEOUT is 0, read returns immediately,
without trying to read any data, returning success only if
input is available on the specified file descriptor. The
exit status is greater than 128 if the timeout is exceeded
所以尝试:
while true
do
echo "$var"
IFS= read -r -t 0.5 -n 1 -s holder && var="$holder"
done
使用该holder
变量是因为变量在与 一起使用时会丢失其内容,read
除非它是只读的(在这种情况下无论如何它都没有用),即使read
超时:
$ declare -r a
$ read -t 0.5 a
bash: a: readonly variable
code 1
我找不到任何方法来阻止这种情况。
答案2
有点晚了,但(更好的)解决方案可能是:
while true ; do
read -r -s -t 0.5; RETVAL=$?
# ok? echo && continue
[ $RETVAL -eq 0 ] && echo -E "$REPLY" && continue
# no timeout ? (EOF or error) break
[ $RETVAL -gt 128 ] || break
done
恕我直言,更大的超时不会伤害任何人,因为一旦新行可用,“读取”就会返回......