developer tip

티에 배관 할 때 stdout의 강제 라인 버퍼링

optionbox 2020. 8. 16. 20:10
반응형

티에 배관 할 때 stdout의 강제 라인 버퍼링


일반적으로 stdout라인 버퍼링됩니다. 즉, printf인수가 개행으로 끝나는 한 해당 행이 즉시 인쇄 될 것으로 예상 할 수 있습니다. 파이프를 사용하여로 리디렉션 할 때 유지되지 않는 것 같습니다 tee.

I는 C ++ 프로그램이 a, 출력 문자열은 항상 \n로 끝나는로를 stdout.

자체적으로 실행되면 ( ./a) 모든 것이 예상대로 올바른 시간에 올바르게 인쇄됩니다. 그러나 tee( ./a | tee output.txt)로 파이프하면 종료 될 때까지 아무것도 인쇄하지 않으므로 tee.

fflush(stdout)C ++ 프로그램에서 각 인쇄 작업 후에 추가하여 수정할 수 있다는 것을 알고 있습니다. 그러나 더 깨끗하고 쉬운 방법이 있습니까? 예를 들어 stdout파이프를 사용하는 경우에도 강제 로 라인 버퍼링 되는 명령이 있습니까?


패키지의 unbuffer일부를 시도하십시오 expect. 이미 시스템에있을 수 있습니다.

귀하의 경우에는 다음과 같이 사용합니다.

./a | unbuffer -p tee output.txt

( -punbuffer가 stdin에서 읽고 나머지 인수의 명령에 전달하는 파이프 라인 모드 용입니다.)


당신은 시도 할 수 있습니다 stdbuf

$ stdbuf -o 0 ./a | tee output.txt

man 페이지의 (큰) 부분 :

  -i, --input=MODE   adjust standard input stream buffering
  -o, --output=MODE  adjust standard output stream buffering
  -e, --error=MODE   adjust standard error stream buffering

If MODE is 'L' the corresponding stream will be line buffered.
This option is invalid with standard input.

If MODE is '0' the corresponding stream will be unbuffered.

Otherwise MODE is a number which may be followed by one of the following:
KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.
In this case the corresponding stream will be fully buffered with the buffer
size set to MODE bytes.

그러나 이것을 명심하십시오.

NOTE: If COMMAND adjusts the buffering of its standard streams ('tee' does
for e.g.) then that will override corresponding settings changed by 'stdbuf'.
Also some filters (like 'dd' and 'cat' etc.) dont use streams for I/O,
and are thus unaffected by 'stdbuf' settings.

에서 실행 stdbuf하고 있지 않고에서 tee실행하고 a있으므로 의 소스 a에서의 스트림 버퍼링을 설정하지 않는 한 이것은 영향을 미치지 않습니다 a.

또한, stdbuf입니다 하지 POSIX하지만, GNU-로 coreutils의 일부입니다.


명령을 사용하여 의사 터미널에서 명령을 실행하려고 할 수도 있습니다 script(파이프에 라인 버퍼 출력을 적용해야 함)!

script -q /dev/null ./a | tee output.txt     # Mac OS X, FreeBSD
script -c "./a" /dev/null | tee output.txt   # Linux

주의 script명령은, 랩 된 명령의 종료 상태를 다시 전파되지 않습니다.


stdio.h에서 setlinebuf를 사용할 수 있습니다.

setlinebuf(stdout);

이렇게하면 버퍼링이 "라인 버퍼링"으로 변경됩니다.

더 많은 유연성이 필요하면 setvbuf를 사용할 수 있습니다.


대신 C ++ 스트림 클래스를 사용하는 경우 every std::endl 암시 적 플러시입니다. C 스타일 인쇄를 사용하면 제안한 방법 ( fflush())이 유일한 방법 이라고 생각합니다 .

참고 URL : https://stackoverflow.com/questions/11337041/force-line-buffering-of-stdout-when-piping-to-tee

반응형