
나는 우분투에서 흥미로운 상태에 빠졌습니다. 아래 단계가 이를 가장 잘 설명합니다.
하나의 파이프로 내가 기대하는 것을 보고 있습니다.
# In shell A
tail -f foo.log | grep aaa
# In shell B
echo aaa >> foo.log
# Shell A prints out `aaa`
하지만 여러 파이프를 사용하면 전혀 아무것도 표시되지 않습니다.
# In shell A
tail -f foo.log | grep aaa | grep bbb
# In shell B
echo aaa bbb >> foo.log
# Nothing ever prints in shell A
하지만 그냥 에코만 하면 괜찮습니다.
echo 'aaa bbb' | grep aaa | grep bbb
이것은 최소한의 재생산을 만들기 위한 나의 시도입니다. 처음에는 adb logcat(Android 개발 도구)에서 로그를 티링하려고 할 때 문제가 발생했습니다. 나는 zsh, bash 및 fish에서도 시도했습니다.
나는 그것이 내 inotify 감시자 제한과 관련이 있다고 생각했지만 부딪혀도 아무 것도 바뀌지 않았습니다.
답변1
이는 일반적으로 라인에 신경 쓰지 않고 데이터를 축적할 수 있는 파이프의 버퍼링 때문입니다.
tail -f
나는 라인 버퍼링을 그 자체로 사용한다고 생각합니다 . 마지막은 grep
tty에 쓰기 때문에 라인 버퍼링도 사용합니다. 따라서 첫 번째 예제가 작동합니다.
하지만 grep
중간에는 다르므로 라인 버퍼링을 강제하거나 버퍼링을 비활성화하여 동작을 조정해야 합니다. 다음 명령은 예상대로 작동합니다.
grep
귀하가 지원하는 경우--line-buffered
(Ubuntu에서는 지원됩니다):tail -f foo.log | grep --line-buffered aaa | grep bbb
보다 일반적인 솔루션(이외의 많은 필터와 함께 작동
grep
):tail -f foo.log | unbuffer -p grep aaa | grep bbb tail -f foo.log | stdbuf -oL grep aaa | grep bbb tail -f foo.log | stdbuf -o0 grep aaa | grep bbb
자세한 내용과 특이한 점은 및 를 man 1 grep
참조 하세요 .man 1 unbuffer
man 1 stdbuf
노트:
- 두 솔루션 모두 이식 가능하지 않습니다(
grep --line-buffered
및 POSIX에서 지정되지 않음).unbuffer
stdbuf
- 당신이 이것을 할 수 있다면
grep --line-buffered
그것은 당신의 선택이어야 합니다. 추가 도구를 사용해도 소용이 없습니다. - Unix 및 Linux SE 관련 질문:파이프에서 버퍼링 끄기.
unbuffer
그리고stdbuf
완전히 다른 방식으로 일하다.- 를 사용하면 여기서는 버퍼링 없음
stdbuf
( )보다 라인 버퍼링-oL
( )을 선호해야 합니다 .-o0
- 성능이 더 좋을 가능성이 높습니다.
- 어쨌든 파이프의 다른 부분에서는 라인 버퍼링을 사용합니다.
- 마지막으로
grep
다른 파일에 쓴 경우 다른 파일처럼 작동합니다grep
. 이러한 경우 최종 파일에 행이 즉시 나타나도록 하려면 마지막grep
. - 에서 가 래퍼 함수인
fish
경우 로 원하는 동작을 얻지 못할 수 있습니다 . 사용 . 이 질문을 참조하세요:grep
--line-buffered
command grep --line-buffered
출력 파이프는 EOF를 기다립니다.fish
.
참고 사항: tail foo.log | grep aaa | grep bbb
(예: tail
없음 -f
)은 종료되기 때문에 문제를 일으키지 않습니다 tail
. 종료 되면 tail
첫 번째는 grep
EOF를 감지하고 버퍼를 플러시하고 종료한 다음 두 번째도 grep
동일한 작업을 수행합니다.