具有非阻塞读取的 Bash 脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4874993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash script with non-blocking read
提问by michelemarcon
I want to send some data to a root process with a named pipe. Here is the script and it works great:
我想使用命名管道将一些数据发送到根进程。这是脚本,效果很好:
#!/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
I actually have several script like this one. I would like to enclose all of them in a single script. The problem is that execution blocks on the first "read" and I cannot execute multiple "reads" in a single process. Isn't there anything I can do? Is it possible to have a "non-blocking" bash read?
我实际上有几个这样的脚本。我想将所有这些都包含在一个脚本中。问题是执行在第一次“读取”时阻塞,我无法在单个进程中执行多个“读取”。我没有什么可以做的吗?是否可以读取“非阻塞”bash?
采纳答案by michelemarcon
Just put the reading cycle into background (add & after done)?
只是将阅读周期置于后台(添加和完成后)?
回答by gabuzo
Bash's read embedded command has a -t parameter to set a timeout:
Bash 的 read 嵌入命令有一个 -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.
This should help you solve this issue.
这应该可以帮助您解决此问题。
Edit:
编辑:
There are some restrictions for this solution to work as the man page indicates: This option has no effect if read is not reading input from the terminal or a pipe.
此解决方案的工作有一些限制,如手册页所示:如果 read 不是从终端或管道读取输入,则此选项无效。
So if I create a pipe in /tmp:
因此,如果我在 /tmp 中创建一个管道:
mknod /tmp/pipe p
Reading directly from the pipe is not working:
直接从管道读取不起作用:
$ read -t 1 </tmp/pipe ; echo $?
Hangs forever.
永远挂起。
$ cat /tmp/pipe | ( read -t 1 ; echo $? )
1
It is working but cat is not exiting.
它正在工作,但 cat 没有退出。
A solution is to assign the pipe to a file descriptor:
一种解决方案是将管道分配给文件描述符:
$ exec 7<>/tmp/pipe
And then read from this file descriptor either using redirection:
然后使用重定向从这个文件描述符中读取:
$ read -t 1 <&7 ; echo $?
1
Or the -uoption of read:
或以下-u选项read:
$ read -t 1 -u 7 ; echo $?
1
回答by Foo Bah
You can use stty to set a timeout. IIRC its something like
您可以使用 stty 设置超时。IIRC它就像
stty -F $pipe -icanon time 0

