tee 发送不完整的数据

Ole*_*nge 2 linux tee

$ head -c10G /dev/zero |
  tee >(head -c1M | wc -c) >(head -c10M | wc -c) >(head -c100M | wc -c) >(head -c1000M | wc -c)
Run Code Online (Sandbox Code Playgroud)

给出:

1048576
1064960
1064960
1064960
Run Code Online (Sandbox Code Playgroud)

我会期望:

1048576
10485760
104857600
1048576000
Run Code Online (Sandbox Code Playgroud)

我想这是由于head -c1M关闭管道tee然后只向其他进程写入一个块,然后才发现它无法写入第一个进程然后退出。

我可以要求tee跳过关闭的接收器,但继续写信给其他人吗?

mos*_*svy 5

你应该使用tee --output-error=exit-nopipe. 这将忽略SIGPIPE信号和EPIPE写入错误,但仍会因任何其他错误而死亡。

tee --output-error=exit-nopipe,就像warn您的答案中的变体一样,当它无法写入至少一个输出时确实会退出;但它确实将标准输出视为其中之一。

您的示例有问题,因为它们只是将输出转储head -c10G /dev/zero | tee ...到您的终端(您看不到,因为空字节是“不可见的”);这就是为什么tee你的答案没有退出:因为在>(...)进程替换退出后它仍然会写入标准输出。

对于没有 GNU tee 的系统,一种可能的解决方法是cat >/dev/null在输出通过tee管道传输到的命令后附加 a ;但你不能对所有这些都这样做;您必须决定一个“主”输出,tee如果写入失败,它将导致退出。例子:

$ dd if=/dev/zero |
  tee >(dd of=/dev/null count=200; cat >/dev/null) >(dd of=/dev/null count=700; cat >/dev/null) |
  dd of=/dev/null count=1000
$ dd if=/dev/zero |
  tee >(dd of=/dev/null count=1000) >(dd of=/dev/null count=700; cat >/dev/null) |
  { dd of=/dev/null count=200; cat >/dev/null; }
Run Code Online (Sandbox Code Playgroud)

两者都应该分别写入 200、700 和 1000 个块。