기본 stdout 버퍼는 어떻게 설정됩니까?

기본 stdout 버퍼는 어떻게 설정됩니까?

Red Hat EL7에서 실행하면 로그 파일에 이렇게 긴 줄이 있어서 다음을 수행했습니다.

tail -f Log | cut -c1-$COLUMNS

이는 일부 시스템에서는 잘 작동하지만 다른(분명히 동일한) 시스템에서는 버퍼가 가득 찰 때까지 파이프가 데이터를 보유합니다. 내가 이것을 입력하는 동안 SE는 나에게이것사용할 때 답변:

tail -f Log | stdbuf -oL cut -c1-$COLUMNS

내가 필요한 것을 수행하지만 차이점이 무엇인지 알고 싶습니다. 나는 시스템이 좋든 나쁘든 동일하게 실행되기를 원합니다.

기본 버퍼링이 설정되어 있나요? 어떻게, 어디에 설정되어 있나요?

업데이트: 문제가 있는 시스템에서 두 개의 창을 열고 시도했습니다.

while date; do usleep 500000 ; done | cut -c1-100

출력이 없습니다(버퍼가 가득 찰 때까지). 다른 창에서 클리핑 프로세스에 대해 strace를 실행했는데 끝없는 일련의 메시지를 받았습니다.

read(0, "Wed Oct 26 13:04:12 CDT 2022\n", 4096) = 29
read(0, "Wed Oct 26 13:04:12 CDT 2022\n", 4096) = 29
read(0, "Wed Oct 26 13:04:13 CDT 2022\n", 4096) = 29
read(0, "Wed Oct 26 13:04:13 CDT 2022\n", 4096) = 29
read(0, "Wed Oct 26 13:04:14 CDT 2022\n", 4096) = 29
read(0, "Wed Oct 26 13:04:14 CDT 2022\n", 4096) = 29
read(0, "Wed Oct 26 13:04:15 CDT 2022\n", 4096) = 29

나는 그것이 컷이 완충 효과를 가지고 있다는 꽤 확실한 증거라고 생각합니다. 그런데 어떻게 이 일을 하기로 결정했습니까?

답변1

일반적인 동작은 터미널에 대한 출력이 라인 버퍼링되고 다른 모든 출력은 블록 버퍼링된다는 것입니다. 예를 들어 참조하십시오.GNU glibc 매뉴얼:

새로 열린 스트림은 일반적으로 완전히 버퍼링되지만 한 가지 예외는 대화형 장치(예: 터미널)에 연결된 스트림이 처음에 라인 버퍼링된다는 것입니다. [...]

그처럼

grep ... | cut ...

있을 것이다grep출력을 버퍼링하지만 버퍼링되지는 않습니다 . (또는 )을 실행하여 이 문제를 해결할 cut수 있습니다 . 또는 다른 많은 해결 방법 중 하나를 사용하세요. 다음을 참조하세요.stdbuf -o0 grep ...grep --line-buffered파이프라인에서 버퍼링 끄기

반면에 tail -f해당 출력은 버퍼링되어서는 안 됩니다.

stdbuf -oL물론 이것은 사용에 대해 말씀하신 것과 일치하지 않습니다.cut수정하세요. 이미 출력을 라인 버퍼링해야 합니다. 터미널로 가면 그렇죠. 있었다면 | cut ... > somefile달랐을 것입니다 .

관련 정보