Bash:如果管道IO空闲则关闭

时间:2016-11-15 19:16:10

标签: linux bash pipe

如果管道流空闲一段时间,如何关闭程序?

比如说:

someprogram | closeidlepipe -t 500 | otherprogram

是否有一些程序closeidlepipe可以在空闲一段时间内关闭(-t 500)?

timeout可以在一段时间后关闭,但不会在"空闲"区别。

更新

重要的是要注意someprogram输出无穷无尽的二进制数据流。数据可能包含空字符\0,应该逐字管道。

2 个答案:

答案 0 :(得分:1)

内置read有一个超时选项-t

someprogram |
  while :; do
    IFS= read -d'' -r -t 500 line
    res=$?
    if [[ $res -eq 0 || )); then
      # Normal read up to delimiter
      printf '%s\0' "$line"
    else
      # Either read timed out without reading another null
      # byte, or there was some other failure meaning we
      # should break. In neither case did we read a trailing null byte
      # that read discarded.
      [[ -n $line ]] && printf '%s' "$line"
      break
    fi
  done | 
  otherprogram

如果read在500秒后超时,while循环将退出,管道的中间部分将关闭。 someprogram下次尝试写入该管道的末尾时会收到SIGCHLD信号,允许它退出。

答案 1 :(得分:1)

这是执行此操作的程序核心的一般形式。

while(1) {
    struct timeval tv;
    tv.m_sec = 0;
    tv.m_usec = 500000;
    int marker = 1;
    select(1, &marker, NULL, NULL, &tv);
    if (marker == 0) exit(1);
    char buf[8192];
    int n = read(0, buf, 8192);
    if (n < 0) exit(2);
    char *b = buf;
    while (n)
    {
        int l = write(1, b, n);
        if (l <= 0) exit(3);
        b += l;
        n -= l;
     }
}