bash:循环内非阻塞读取

bash:循环内非阻塞读取

我有一个以下的小 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

恕我直言,更大的超时不会伤害任何人,因为一旦新行可用,“读取”就会返回......

相关内容