파이프라인에서 "ping" 출력의 각 라인을 즉시 처리합니다.

파이프라인에서 "ping" 출력의 각 라인을 즉시 처리합니다.

나는 그것으로부터 타이밍 정보를 추출하는 다양한 방법의 몇 가지 예를 가지고 있습니다 ping -c 10 google.com. 이러한 파이프 중 일부의 경우 ping 출력과 마찬가지로 가끔씩 출력 라인이 생성됩니다. 다른 출력 라인의 경우 모든 출력 라인이 처리된 후 즉시 모든 출력 라인이 방출됩니다. 첫 번째 행동을 볼 시기와 두 번째 행동을 볼 시기를 결정하는 좋은 규칙이 있나요?

# prints output for each line as soon as it is received
# on OS X and Linux.
ping -c 10 google.com | grep -o 'time=\S*'

# prints output for each line as soon as it is received on OS X
# but not on Linux 
# (the output of ping is slightly different so it's $8 on Linux to get the time)
ping -c 10 google.com | awk '{ print $7 }'

# waits until all input is received on OS X and Linux
ping -c 10 google.com | awk -F ':' '{ print $2 }'

# prints output for line as soon as it is received on Linux and OS X
ping -c 10 google.com | sed -e 's/^.*time=\(.*\) .*$/\1/'

# waits for the end of input on OS X and Linux
ping -c 10 google.com | grep -o 'time\S*' | sed -e 's/time=//'

# as a quick check, this prints each line of output immediately 
# on OS X and Linux
ping -c 10 google.com | sed -e 's/time=//' 

둘러본 후에 이것은 라인 버퍼링의 문제일 뿐이며 일부 표준 유틸리티는 대화식으로 사용할 때와 비대화식으로 사용할 때 다르게 동작하는 것 같습니다.

답변1

이러한 프로그램에서 버퍼링을 처리하는 방법에 대한 것입니다.

grep이 파이프된 데이터를 즉시 출력하도록 하려면 --line-buffered 옵션과 함께 이를 사용하십시오.

ping -c 10 google.com | grep --line-buffered -o 'time\S*' | sed -e 's/time=//'

awk가 파이프된 데이터를 즉시 출력하도록 하려면 -W Interactive 옵션을 사용하십시오.

ping -c 10 google.com | awk -W interactive '{ print $7 }'

자세한 내용을 보려면 해당 응용 프로그램의 매뉴얼 페이지를 읽어야 합니다.

답변2

이러한 버퍼링은 관련된 설명자가 tty가 아닌 경우 파이프에 의해 수행됩니다. 일부 명령에는 이를 처리하고 대화형 동작을 적용하는 특정 옵션이 있습니다.

이 문제를 해결하는 일반적인 방법

당신은 그것을 사용할 수 있습니다stdbufGNU Coreutils에서. stdin, 및 stdout의 버퍼링을 관리합니다 stderr. 로 설정하여 완전히 비활성화하거나 0다음으로 설정하여 라인 버퍼링을 사용할 수 있습니다 L.

stdbuf -i0 -o0 -e0 command
stdbuf -oL ping example.com

이 명령은 setvbuf()해커 설정을 통해 작동합니다 LD_PRELOAD. 호출된 명령이 강제로 해당 함수를 다시 호출하는 경우 stdbuf버퍼링이 비활성화되지 않을 수 있습니다.

당신은 또한 사용할 수 있습니다unbuffer명령은 본질적으로 동일한 결과를 얻습니다. 이 명령은 기본적으로 관련이 expect있으며 설치되지 않을 수 있습니다. 기본적으로 다음과 같이 사용할 수 있습니다.

unbuffer command

명령별 옵션

명령별 버퍼링과 관련하여 비활성화하는 방법은 다음과 같습니다.

  • grep버퍼링을 비활성화하는 GNU 옵션:--line-buffered
  • sed버퍼링을 비활성화하는 GNU 옵션:-u
  • awkGNU는 제어 tty가 없을 때 버퍼링을 하지 않습니다.
  • mawk, 최소한 Debian/Ubuntu의 기본 awk,하다출력 버퍼링.mawk 가능한사용할 수 없으며 버퍼링을 비활성화하는 옵션을 stdbuf제공합니다 .-Winteractive

관련 정보