mic*_*con 8 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
Run Code Online (Sandbox Code Playgroud)
我实际上有几个像这样的脚本.我想将所有这些内容放在一个脚本中.问题是第一次"读取"时执行阻塞而我无法在单个进程中执行多次"读取".我有什么办法吗?是否可以进行"非阻塞"bash读取?
gab*_*uzo 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.
Run Code Online (Sandbox Code Playgroud)
这应该可以帮助您解决此问题.
编辑:
此解决方案有一些限制,因为手册页指示:如果读取不是从终端或管道读取输入,则此选项无效.
所以,如果我在/ tmp中创建一个管道:
mknod /tmp/pipe p
Run Code Online (Sandbox Code Playgroud)
直接从管道读取不起作用:
$ read -t 1 </tmp/pipe ; echo $?
Run Code Online (Sandbox Code Playgroud)
永远挂起.
$ cat /tmp/pipe | ( read -t 1 ; echo $? )
1
Run Code Online (Sandbox Code Playgroud)
它正在发挥作用,但猫并没有退出.
解决方案是将管道分配给文件描述符:
$ exec 7<>/tmp/pipe
Run Code Online (Sandbox Code Playgroud)
然后使用重定向从此文件描述符中读取:
$ read -t 1 <&7 ; echo $?
1
Run Code Online (Sandbox Code Playgroud)
或-u
选项read
:
$ read -t 1 -u 7 ; echo $?
1
Run Code Online (Sandbox Code Playgroud)
小智 3
只是将阅读周期放入后台(完成后添加&)?