带有非阻塞读取的Bash脚本

时间:2011-02-02 13:28:40

标签: bash scripting nonblocking

我想将一些数据发送到具有命名管道的根进程。这是脚本,它很有用:

#!/bin/sh
pipe=/tmp/ntp

if [[ ! -p $pipe ]]; then
    mknod -m 666 $pipe p
fi

while true
do
    if read line <$pipe; then
         /root/netman/extra/bin/ntpclient -s -h $line > $pipe 2>&1
    fi
done

我实际上有几个像这样的脚本。我想将所有这些内容放在一个脚本中。问题是第一次“读取”时执行阻塞而我无法在单个进程中执行多次“读取”。我有什么办法吗?是否可以进行“非阻塞”bash读取?

3 个答案:

答案 0 :(得分:18)

Bash的read embedded命令有一个-t参数来设置超时:

-t timeout
    Cause read to time out and return failure if a complete line of input is not
    read within timeout seconds. This option has no effect if read is not reading
    input from the terminal or a pipe.

这可以帮助您解决此问题。

编辑:

此解决方案有一些限制,因为手册页指示:如果读取不是从终端或管道读取输入,则此选项无效。

所以如果我在/ tmp:

中创建一个管道
mknod /tmp/pipe p

直接从管道中读取不起作用:

$ read -t 1 </tmp/pipe  ; echo $?

永远挂起。

$ cat /tmp/pipe | ( read -t 1 ; echo $? )
1

它正在运作,但是猫没有退出。

解决方案是将管道分配给文件描述符:

$ exec 7<>/tmp/pipe

然后使用重定向从该文件描述符中读取:

$ read -t 1 <&7  ; echo $?
1

-u的{​​{1}}选项:

read

答案 1 :(得分:3)

只需将阅读周期放入后台(添加和完成后)?

答案 2 :(得分:-1)

您可以使用stty设置超时。 IIRC就像

stty -F $pipe -icanon time 0