파이프 체인 내에서 jq를 사용하면 출력이 생성되지 않습니다 필터를 사용하는 경우에도 파이프 체인의

jq출력이 리디렉션 될 때 명시 적 필터 가 필요한 문제 는 웹 전체에서 논의됩니다. 그러나 jq명시 적 필터를 사용하는 경우에도 파이프 체인의 일부인 경우 출력을 리디렉션 할 수 없습니다 .

치다:

touch in.txt
tail -f in.txt | jq '.f1'
# in a different terminal:
echo '{"f1":1,"f2":2}' >> in.txt
echo '{"f1":3,"f2":2}' >> in.txt

예상 한대로 jq명령 의 원래 터미널 출력 은 다음과 같습니다.

1
3

그러나 jq명령 끝에 리디렉션 또는 파이핑을 추가 하면 출력이 자동으로 진행됩니다.

rm in.txt
touch in.txt
tail -f in.txt | jq '.f1' | tee out.txt
# in a different terminal:
echo '{"f1":1,"f2":2}' >> in.txt
echo '{"f1":3,"f2":2}' >> in.txt

첫 번째 터미널에 출력이 나타나지 않고 out.txt가 비어 있습니다.

수백 가지 변형을 시도했지만 찾기 어려운 문제입니다. 은 내가 찾은 해결 을 통해 발견으로, mosquitto_sub그리고 (나는 또한 문제가 발견 된 곳이었다)없는 것들 네트워크, 꼬리 래핑하는 것입니다 쉘 스크립트에서 JQ 기능 :

#!/bin/bash
tail -f $1 | while IFS='' read line; do
echo $line | jq '.f1'
done

그때:

./tail_and_jq.sh | tee out.txt
# in a different terminal:
echo '{"f1":1,"f2":2}' >> in.txt
echo '{"f1":3,"f2":2}' >> in.txt

그리고 충분히 출력이 나타납니다.

1
3

jqHomebrew를 통해 최신 버전으로 설치되어 있습니다.

$ echo $SHELL
/bin/bash
$ jq --version
jq-1.5
$ brew install jq
Warning: jq 1.5_3 is already installed and up-to-date

이것은 jq파이프 체인에 대한 이해와 관련 이 있거나 (문서화되지 않은) 버그 입니까?



답변

로부터의 출력은 jq표준 출력이 파이프 때 버퍼링된다.

jq모든 객체 후에 출력 버퍼 를 플러시하도록 요청하려면 --unbuffered옵션을 사용하십시오.

tail -f in.txt | jq --unbuffered '.f1' | tee out.txt

로부터 jq수동 :

--unbuffered

각 JSON 객체가 인쇄 된 후 출력을 플러시합니다 (느린 데이터 소스를 jq파이핑하고 jq다른 곳의 출력을 파이핑하는 경우 유용 ).


답변

여기서보고있는 것은 C stdio 버퍼링 작동입니다. 특정 한계 (512 바이트 또는 4KB 이상)에 도달 할 때까지 출력을 버퍼에 저장 한 다음 한 번에 전송합니다.

이 버퍼링은 stdout이 터미널에 연결된 경우 자동으로 비활성화되지만 파이프와 같은 경우 (예 : 경우와 같이)이 버퍼링 동작을 활성화합니다.

버퍼링을 비활성화 / 제어하는 ​​일반적인 방법은 setvbuf()기능을 사용하는 것입니다 ( 자세한 내용 은 이 답변 참조). 소스 코드 jq자체 에서 수행해야 하므로 실제적이지 않을 수도 있습니다 …

해결 방법이 있습니다 … (해킹, 아마도 말할 수 있습니다.) “언 버퍼”라는 프로그램이 있습니다. “버퍼”는 의사 터미널을 만들고 프로그램에 연결할 수있는 “expect”로 배포됩니다. 따라서 jq파이프에 계속 쓰 더라도 터미널에 쓰고 있다고 생각하고 버퍼링 효과가 비활성화됩니다.

“expect”패키지를 설치하십시오. 만약 “unbuffer”가 없다면, 데비안 (또는 우분투)에 설치하십시오 :

$ sudo apt-get install expect

그런 다음이 명령을 사용할 수 있습니다.

$ tail -f in.txt | unbuffer -p jq '.f1' | tee out.txt

“언 버퍼”에 대한 자세한 내용은 이 답변참조하십시오 . 맨 페이지도 여기에서 찾을 수 있습니다 .