tee가 불완전한 데이터를 보냅니다.

tee가 불완전한 데이터를 보냅니다.
$ head -c10G /dev/zero |
  tee >(head -c1M | wc -c) >(head -c10M | wc -c) >(head -c100M | wc -c) >(head -c1000M | wc -c)

다음을 제공합니다:

1048576
1064960
1064960
1064960

나는 예상했을 것입니다 :

1048576
10485760
104857600
1048576000

head -c1M나는 이것이 파이프를 닫고 tee다른 프로세스에 블록을 쓴 다음 첫 번째 프로세스에 쓸 수 없다는 것을 발견하고 종료하기 때문이라고 생각합니다 .

tee비공개 수신자를 건너뛰고 다른 수신자에게는 계속해서 쓰도록 요청할 수 있습니까 ?

답변1

을 사용해야 합니다 tee --output-error=exit-nopipe. 이는 SIGPIPE신호를 무시하고 EPIPE오류를 기록하지만 다른 오류에서는 여전히 종료됩니다.

tee --output-error=exit-nopipe, warn답변의 변형과 마찬가지로 하나 이상의 출력에 쓸 수 없으면 종료되지만 표준 출력은 그 중 하나로 간주됩니다.

귀하의 예제는 출력을 head -c10G /dev/zero | tee ...터미널에 덤프하기 때문에 버그가 있습니다(널 바이트가 "보이지 않기" 때문에 볼 수 없음). 이것이 바로 tee응답이 종료되지 않는 이유입니다. >(...)프로세스 교체가 종료된 후에도 여전히 쓰기 때문입니다. 표준 출력.

GNU tee가 없는 시스템의 경우 가능한 해결 방법은 파이프하는 cat >/dev/null명령에 a를 추가하는 것입니다. 그러나 모든 명령에 대해 tee그렇게 할 수는 없습니다. 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; }

둘 다 각각 200, 700 및 1000 블록을 써야 합니다.

답변2

--output-error=warn이런 기능도 있는 것 같더라구요

head -c10G /dev/zero |
  tee --output-error=warn >(head -c10M | wc -c) >(head -c100M | wc -c) >(head -c1000M | wc -c)

불행하게도 stderr에 대한 경고도 스팸으로 보내고 어느 쪽에도 쓸 수 없으면 종료되지 않습니다.

답변3

SIGPIPE를 보내는 모든 차단된 파이프는 tee이를 중지합니다.

$ head -c10G /dev/zero |   tee >(head -c10 | wc -c) >(head -c1M | wc -c)
10
65536

이 명령은 tee첫 번째 파이프에서 SIGPIPE를 수신하고 모든 하위 파이프가 종료되도록 합니다.

제한이 없도록 각 파이프를 확장해야 합니다.

$ head -c10G /dev/zero |   tee >({ head -c10 | wc -c; }; cat >/dev/null )  >(head -c1M | wc -c)
10
1048576

귀하가 제공한 모든 사례에 대해:

$ head -c10G /dev/zero |   tee >({ head -c1M | wc -c;}; cat >/dev/null) >({ head -c10M | wc -c; }; cat >/dev/null) >( { head -c100M | wc -c; }; cat>/dev/null) >(head -c1000M | wc -c)
1048576
10485760
104857600
1048576000

tee그러나 다음 옵션을 사용하면 파이프 오류로 인해 종료되는 것을 방지하는 것이 더 쉽습니다 -p.

$ head -c10M /dev/zero |   tee -p >(head -c10 | wc -c) >(head -c100 | wc -c) >(head -c1000| wc -c) >(head -c1M | wc -c)
100
1000
10
1048576

이는 순서대로 인쇄되지 않을 수 있습니다.

관련 정보