La questione della jq
necessità di un filtro esplicito quando viene reindirizzato l'output è discussa in tutto il Web. Ma non riesco a reindirizzare l'output se jq
fa parte di una catena di pipe, anche quando è in uso un filtro esplicito.
Ritenere:
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
Come previsto, l'output nel jq
comando originale dal comando è:
1
3
Ma se aggiungo qualsiasi tipo di reindirizzamento o piping alla fine del jq
comando, l'output diventa silenzioso:
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
Nessun output appare nel primo terminale e out.txt è vuoto.
Ho provato centinaia di varianti ma è un problema sfuggente. L'unica soluzione che ho trovato , come scoperto attraverso mosquitto_sub
e The Things Network (che era anche il punto in cui ho scoperto il problema), è di avvolgere le funzioni tail e jq in uno script shell:
#!/bin/bash
tail -f $1 | while IFS='' read line; do
echo $line | jq '.f1'
done
Poi:
./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
E abbastanza sicuro, l'output appare:
1
3
Questo è con l'ultimo jq
installato tramite 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
Si tratta di un bug (ampiamente non documentato) all'interno jq
o con la mia comprensione delle catene di tubi?
tail -f logfile | grep 'foo bar' | awk ...
tail
bit è nato dagli sforzi per rompere il pipe (esegui il primo comando, tee e reindirizza al file, coda quello, pipe al comando successivo, reindirizza al file, ecc.) Ed eseguilo continuamente in sezioni. È comunque <
un buon strumento da tenere a mente.
tail -f
per fornire input continuo a un programma edtee
elaborare l'output. Se avessi ancora bisogno di una risposta, avrei suggerito di semplificare la catena in<in.json jq '.f1' >out.json
modo da poter restringere la causa.