진행률 표시줄이 포함된 출력을 실시간으로 grep하는 방법은 무엇입니까?

진행률 표시줄이 포함된 출력을 실시간으로 grep하는 방법은 무엇입니까?

openocd저는 쓰레기를 많이 인쇄하는 도구( )를 사용하고 있는데 , 기본 진행률 표시줄이 천천히 간단한 점을 인쇄한 다음 다시 일부 쓰레기를 인쇄합니다.

grep진행률 표시줄이 있는 행만 실시간으로 표시되도록(즉, 각 출력 지점이 openocd터미널에 즉시 인쇄되도록) 이 출력을 필터링하고 싶습니다 .

openocd <args> |& grep '^\.'

문제는 grep(기껏해야) 라인 버퍼링이므로 완료될 때까지 진행률 표시줄이 표시되지 않는다는 것입니다.

이 문제를 어떻게 해결해야 합니까? grep아니면 이를 달성하기 위한 표준 대안이 있습니까? openocd저는 좀 더 일반적인 솔루션을 선호하지만 구성을 통한 방법이 있다면 유용할 것입니다.

답변1

이것은 해키적이고 특이한 답변입니다. 사실 이것은 그다지 깨끗하지 않은 방식으로 구현되었을 가능성이 높습니다.


grep자체적으로는 개행 문자가 나타날 때만 출력을 인쇄하는 것처럼 보이며, 업데이트할 때 진행률 표시줄에 개행 문자가 표시되지 않을 수 있으므로 문제가 발생합니다.

strace명령이 호출하는 시스템 호출을 보기 위한 도구입니다. 여기에는 메모리/저장소에 대한 읽기 및 쓰기, 파일 설명자 열기/닫기 등과 같은 작업이 포함됩니다.


파이프가 전달되면 strace프로세스가 액세스하는 내용을 볼 수 있으므로 텍스트가 제공되는 것을 볼 수 있습니다. 파이프된 명령의 출력은 주기적으로 전송되며 해당 출력을 스니핑하여 표시할 수 있습니다. 테스트 중인데 비슷한 상황이 발생하는 것 같습니다. 진행 상황을 보여주기 위해 사용했습니다.stoutgrepstracegrepstracersync --progressgrep##%rsync

rsync --progress file1 file2 | strace -e trace=read grep "[0-9]*%"

이 명령을 실행하면 strace출력이 좋지 않다는 것을 알 수 있지만, 이 명령을 사용하면 일반적으로 표시되지 않는 strace일부 s를 캡처하여 s를 0%, 21%, 45%, 68%로 표시합니다. read91% 및 100%는 매초마다 업데이트되는 것으로 보입니다(아마도 진행 상황이 업데이트되는 빈도에 따라 달라질 수 있음).rsyncgrepwritereadrsync

따라서 동일한 출력을 다시 호출하면 덜 좋은 출력을 얻을 수 있습니다 grep.stracegrep

rsync --progress file1 file2 | strace -e trace=read grep "[0-9]*%" 2>&1 > /dev/null | grep -o "[0-9]*%"

첫 번째 출력이 보고되지 않도록 .redirects 로 인쇄하기 2>&1때문에 중요합니다 . 최종 결과는 다음과 같습니다.stracestderr> /dev/nullstdout/dev/nullgrep

0%
21%
45%
68%
91%
100%

교체해야 grep하지만 효과가 있을 것 같습니다. 예쁘지는 않지만 작동하고 우회할 수 있습니다 . 이와 같은 것이 편리할 grep것 같습니다 ( 이미 사용되고 있다는 것을 알고 있습니다 ).grep -ftail -fgrep -f

첫 번째는 grep주로 실행될 텍스트를 필터링하는 것입니다 strace. read왜냐하면 일치하는 줄만 호출에 나열되기 때문입니다 strace. 그러나 텍스트 를 볼 수 read있도록 이동하려면 뭔가가 필요합니다 .strace

답변2

최종 답변은 매우 복잡하기 때문에 Centimane의 답변을 사용합니다.

이미 꽤 진부해졌는데...지금은 정말 나빠지고 있습니다.

make flash \
    |& strace -e trace=read grep -e "^\." -e rror \
    |& stdbuf -o0 sed -ne 's/^.*"\.".*/\./p;/rror/p' \
    | stdbuf -o0 tr -d '\n' \
    ; echo

그래서 make flash위의 내용은 호출입니다 openocd.

strace위에서 설명한 Centimane의 해킹을 사용합니다.

sedread(0, ".", xxx)행을 단일 행으로 바꾸십시오 ..

tr모든 것을 .한 줄에 유지하면서 마지막 에코는 유일한 EOL을 배치하는 것입니다.

무엇보다도 sed및 호출은 stdout 버퍼 크기를 0으로 설정하고(EOL이 제거되었기 때문에) 오류 시 일부 가비지 인쇄와도 일치합니다.trstdbuf -o0grep/sed(e)rror

나는 이러한 모든 부풀어오르는 요인을 최소한으로 분해하려고 노력했지만 더 잘할 수 없었습니다.

또한 저는 zsh/Ubuntu 14.04를 사용하고 있으며 이것이 다른 Unix에서도 작동할지 확신할 수 없습니다.

관련 정보