jq
出力がリダイレクトされるときに明示的なフィルターが必要な問題は、Web全体で説明されています。しかし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は空です。
私は何百ものバリエーションを試しましたが、それはとらえどころのない問題です。The Things Network(問題も発見した場所)で発見したように、私が見つけた唯一の回避策mosquitto_sub
は、tail および 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
これはjq
Homebrew経由でインストールされた最新のものです:
$ 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
、パイプチェーンを理解している、または理解している(ほとんど文書化されていない)バグですか?
tail -f logfile | grep 'foo bar' | awk ...
tail
ビットはパイプを分解する努力から生じました(最初のコマンドを実行し、ファイルにティーし、リダイレクトし、次のコマンドにパイプし、ファイルにリダイレクトするなど)、セクションで連続して実行します。<
けれども心に留めておくための良いツールです。
tail -f
は、プログラムに連続入力を提供しtee
、出力を処理するために使用する、かなり(まあ、少し)奇妙なセットアップがあります。それでも答えが必要な場合は、<in.json jq '.f1' >out.json
原因を絞り込めるように、チェーンを単純化することをお勧めします。