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

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

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

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

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

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

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

답변1

이것은 일종의 해킹적이고 특이한 답변입니다. 사실 이는 그다지 깨끗하지 않은 방식으로 가능할 가능성이 높습니다.


grep자체적으로 개행 문자가 발견될 때만 출력을 인쇄하는 것처럼 보이며 진행률 표시줄이 업데이트될 때 개행 문자를 도입하지 않을 가능성이 높으므로 문제가 발생합니다.

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


파이프가 에 전달되는 strace경우 프로세스가 액세스하는 내용을 볼 수 있으므로 에 공급되는 텍스트를 볼 수 있습니다 . 파이프된 명령의 출력이 정기적으로 전송되며 해당 출력을 스니핑하여 표시할 수 있습니다. 비슷한 시나리오가 발생하는 것 같습니다 . 나는 진행 상황을 표시하는 데 사용되기 때문에 the를 사용했습니다 .stoutgrepstracegrepstracersync --progressgrep##%rsync

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

strace이 명령을 실행하면 좋은 결과가 나오지 않지만 내가 사용했을 때 일반적으로 발생 하지 않는 strace몇 가지 reads를 포착하여 0%, 21%, 45%, 68%에 대해 s를 표시한다는 것을 알 수 있습니다 . 91%와 100%는 매초마다 업데이트되는 것 같았습니다(아마도 진행 상황을 업데이트하는 빈도에 따라 다름).rsyncgrepwritereadrsync

따라서 이를 다시 호출하면 별로 좋지 않은 출력을 grep얻을 수 있습니다 .stracegrep

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

에 인쇄되기 때문에 가 2>&1중요합니다 . 첫 번째 출력이 보고되는 것을 방지하기 위해 리디렉션 됩니다 . 최종 결과는 다음과 같습니다.stracestderr> /dev/nullstdout/dev/nullgrep

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

를 교체해야 grep하지만 효과가 있을 것 같습니다. 예쁘지는 않지만 grep. grep -f작동하는 것이 편리할 것 같습니다 ( 이미 사용 중이라는 tail -f것을 알고 있습니다 ).grep -f

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

답변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모든 것을 .한 줄에 유지하고 final echo는 유일한 EOL을 넣습니다.

그 외에도 stdout 버퍼 크기를 0으로 설정하는(EOL이 제거되었기 때문에) 및 오류가 발생할 경우 일부 쓰레기를 인쇄하기 위해 일치하는 sed호출 도 있습니다 tr.stdbuf -o0grep/sed(e)rror

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

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

관련 정보