나는 이 문제를 해결하려고 노력하고 있습니다. 나는 다음 줄을 가지고 있습니다 :
mplayer *.* 2>/dev/null | grep Playing
방금 시작되었고 mplayer
일치하는 줄만 화면에 인쇄되었습니다. 이는 현재 재생 중인 미디어를 변경할 때마다 작동합니다.Playing filename
grep 의 출력을 "형식화"하는 것이 가능한지 궁금합니다. 예를 들어 출력이 다음과 같은 경우:
Playing Pink_Floyd-Wish_You_Were_Here.mp3 # I get this at the beginning
Playing Pearl_Jam-Once.mp3 # I get this after I change media inside mplayer
그러면 나는 다음과 같은 것을 갖게 될 것입니다 :
Mplayer: Playing Pink_Floyd-Wish_You_Were_Here.mp3
Mplayer: Playing Pearl_Jam-Once.mp3
이를 위해 awk를 사용하기로 결정했습니다.
mplayer *.* 2>/dev/null | grep Playing | awk '{print "Mplayer: "$1}'
하지만 이 경우에는 아무 일도 일어나지 않습니다.
내 질문은 mplayer의 문제를 해결하기 위한 것이 아니라 bash의 파이프에 대한 더 깊은 이해를 얻기 위한 것입니다.
예를 들어, 다음을 사용한다면:
echo a_song.mp3 | awk '{print "Mplayer: "$1}'
나는 내가 원하는 것을 얻습니다
Mplayer: a_song.mp3
첫 번째 명령이 작동하지 않는 이유는 무엇입니까?
백그라운드에서 이러한 프로세스를 여러 개 실행하려면 어떻게 해야 합니까?
답변1
많은grep표준 출력이 터미널인 경우 구현에서는 라인 버퍼링을 사용합니다. 표준 출력이 터미널인 경우 일반적으로 대화형 세션이므로 가능한 한 빨리 데이터를 얻으려고 합니다. 따라서 grep
개행 문자가 표시되는 즉시 데이터가 표준 출력에 기록됩니다.
표준 출력이 터미널이 아닌 경우(일반적으로 비대화형 세션을 의미) grep
블록 버퍼가 사용됩니다. 이는 grep
개행 문자가 보일 때 표준 출력이 즉시 작성되지 않음을 의미합니다. grep
표준 출력에 쓰기 전에 많은 양의 데이터(Linux의 경우 4096바이트)를 수집합니다.
일부 grep
버전, 예:GNU grep또는BSD grep가지다--라인 버퍼링옵션. grep
개행 문자가 표시되면 항상 표준 출력에 씁니다. 따라서 귀하의 예는 다음과 같습니다.
mplayer *.* 2>/dev/null | grep --line-buffered Playing | awk '{print "Mplayer: "$1}'
grep
귀하의 버전이 그렇지 않은 경우 --line-buffer
다음을 사용하여 모든 작업을 수행할 수 있습니다 awk
.
mplayer *.* 2>/dev/null | awk '/Playing/{print "Mplayer: "$1}'
GNU coreutils에는 도구가 있습니다표준 버퍼명령 수정을 위한 버퍼입니다. 다음을 사용하여 언제든지 표준 출력에 라인 버퍼를 강제로 적용할 수 있습니다.
stdbuf -oL command
게다가버퍼링 해제출력 버퍼링을 비활성화하는 명령만 해당됩니다.
추가 읽기