如何正确取消缓冲管道?

如何正确取消缓冲管道?

我正在尝试遵循各种答案,线程,但我的管道仍然显示为缓冲。这是一个尝试示例:

unbuffer sh -c 'echo -n test; sleep 1; echo; sleep 1; echo -n hello; sleep 1; echo' | grep .

上面的命令应该立即 print test,然后在第二次 print 后hello,再一秒结束后。相反,我得到了一秒钟的延迟,然后test,然后,经过一段时间- 第二次延迟,hello命令退出。

请注意,我在这里试图完全地摆脱缓冲,并且--line-buffered选项grep不会有帮助。那么,我如何真正解除这条管道的缓冲呢?

答案1

grep将输出线与模式匹配,因此在读取整行(或文件结尾,如果最后一行未终止,则行为根据实现而变化)之前,它无法输出任何内容。

所以在:

(echo -n foo; sleep 1; echo bar) | grep .

不是因为echo 缓冲其输出。事实并非如此。一旦它终止了,怎么可能呢?这是因为grep正在等待行尾(即将到来,紧接着是第二个文件结束符echo)。

要执行您似乎想要的操作,您需要读取每行都有超时的行,例如(带有bash):

(echo -n foo; sleep 1; echo bar) |
  while true; do
    TMOUT=0.1 IFS= read -r line; ret=$?
    if [ "$(kill -l "$ret")" = ALRM ]; then
      [ -n "$line" ] || continue
      ors=
    elif [ "$ret" -eq 0 ]; then
      ors=$'\n'
    elif [ -z "$line" ]; then
      break
    fi
    [[ $line =~ . ]] && printf %s "$line$ors"
  done

(至少每 0.1 秒在循环中获得一次通过)。

相关内容