tr에 대한 버퍼링을 비활성화 할 수 있습니까?


10

trLongRunningCommand|tr \\n ,LongRunningCommand에서 몇 킬로바이트의 입력이 누적 된 후에 만이 명령 이 출력 생성을 시작 하도록 입력을 버퍼링하는 것 같습니다 .

tr이 버퍼링 또는 버퍼링없이 개행을 다른 문자로 바꿀 수있는 다른 명령 을 강제 로 중지 하는 방법 이 있습니까?


추신 : 나는 파이프에서 버퍼링 끄기에서 성공하지 않고 처음 두 가지 제안을 이미 시도했습니다 .


1
당신이 적용 않았다 stdbuf다르게, 그럴 LongRunningCommand로하거나, 또는 둘 다?
meuh

둘 다 이렇게 :stdbuf -o0 fping -aAq -r2 -g 10.30.0.1 10.30.0.255 2>/dev/null | stdbuf -i0 tr \\n ,
ndemou

fping -q"프로브 당 결과는 표시하지 말고 최종 요약 만 표시하십시오."라고 말하면 결국에는 한 번만 쓸 수 있습니까?
meuh

fping 명령 자체는 제대로 작동하지 않습니다. 제안에 감사드립니다
ndemou

2
버퍼링 문제는 실제로의 출력 에 있다고 생각합니다 tr. 시도|stdbuf -i0 -o0 tr ...
meuh

답변:


12

명령은 일반적으로 입력을 버퍼링하지 않습니다. 그들은 read()큰 청크에 대해 할 것이지만 파이프에서 읽을 때 파이프에 많은 바이트가 없으면 read()시스템 호출은 많은 문자로 반환되며 응용 프로그램은 일반적으로 가능한 경우 .

주목할만한 예외 는 입력 버퍼가 가득 찰 때까지 mawk계속 유지됩니다 read().

응용 프로그램은 출력 (stdout)을 버퍼링합니다 . 일반적인 동작은 출력이 tty로 가고 있다면 버퍼링은 줄 단위입니다 (즉, 출력 할 줄이 생길 때까지 또는 stdout에 쓰기를 시작하지 않습니다). 긴 줄), 다른 모든 유형의 파일에 대해 버퍼링은 블록 단위입니다 (즉, 하나의 블록이 쓸 수있을 때까지 쓰기가 시작되지 않습니다 (4KiB / 8KiB와 같은 것은 소프트웨어 및 시스템에 따라 다름) )).

따라서 귀하의 경우 LongRunningCommand출력은 블록으로 버퍼링되고 (출력은 tty가 아닌 파이프 tr이므로) 출력은 아마도 터미널이기 때문에 라인별로 출력을 버퍼링합니다.

그러나 출력에서 ​​모든 개행 문자를 제거하므로 행을 출력하지 않으므로 버퍼링은 블록 단위입니다.

여기에서 LongRunningCommand와에 대한 버퍼링을 비활성화하고 싶습니다 tr. GNU 또는 FreeBSD 시스템에서 :

stdbuf -o0 LongRunningCommand | stdbuf -o0 tr '\n' ,

쉼표로 줄을 결합하려면 더 나은 방법을 사용하는 것 paste -sd , -입니다. 그렇게하면 출력이 개행 문자로 종료됩니다 (아직 버퍼링을 비활성화해야 할 수도 있습니다).


@mikeserv. 예, stdio 버퍼링을 사용하고 setvbuf / setbuffer를 호출하지 않고 자체적으로 쉘 내장이 아닙니다. 그러나 일반적으로 GNU 및 FreeBSD 시스템에서는 이러한 모든 조건이 충족됩니다.
Stéphane Chazelas

오. 나는 단지 며칠 전 내가 정적으로 컴파일 된 I / O 스트림에 영향을 줄 수 없다는 것에 실망했을 때만 나 자신을 배웠다 sed. 그것이 성가신 경우 죄송합니다-그러나 나는 그것이 일반적인 지식이라는 것을 몰랐습니다. LD_PRELOAD를 사용한다고 생각합니다.
mikeserv

스테판의 상황에 대한 철저한 설명에 감사드립니다. 대단히 감사
ndemou

5

개행을로 바꾸려면 ","다음을 실행하십시오.

awk '{ printf "%s,", $0 }'

GNU awk ( gawk) 및 Solaris nawk는 stdin에서 라인 버퍼링으로 실행되며 출력이 터미널에있을 때 버퍼링 stdout이 없습니다. awk가 mawkUbuntu에서 발생하는 경우 -W interactive동일한 버퍼링 동작을 얻을 수 있는 옵션을 제공 할 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.