
Às vezes quero inserir algo em um pipeline para geração de relatórios ou algum outro uso secundário. Pode ser tão simples quanto wc -l
, ou uma fera mais complexa awk
ou até mesmo um script python. Seria bom executar um pipeline como este:
zcat my_data_file.gz \
| wc -l > /tmp/linecount
| process_data.py
O problema é que a maioria dos utilitários não corrige os dados para stdout. tee
posso gravar os dados em um arquivo temporário, mas então tenho que esperar até que tudo esteja pronto:
zcat my_data_file.gz \
| tee /tmp/f \
| process_data.py && \
wc -l /tmp/f > /tmp/linecount && rm /tmp/f
Isto não é o ideal: pode ser um pipeline de execução muito longa; Talvez eu queira ver resultados intermediários do analógico mais wc
cedo; e talvez eu não queira armazenar todos os dados em um arquivo temporário.
Responder1
Você pode usar tee
e processar a substituição >(...)
para isso:
zcat my_data_file.gz |
# Count number of lines in stream
tee >(wc -l > /tmp/linecount) |
# Further processing
process_data.py
Observe que pipes podem ser usados para continuação de linha e que comentários podem ser intercalados entre comandos, um recurso interessante ao construir pipelines complicados.
Responder2
Não é totalmente eficiente, mas você pode conseguir isso comtubos nomeados, que você pode criar commkififo(1)
Para o exemplo da pergunta:
mkfifo /tmp/f
wc -l /tmp/f > /tmp/linecount &
zcat my_data_file.gz \
| tee /tmp/f \
| process_data.py &
wait
rm /tmp/f
Observe o &
anexo a ambos wc
e ao pipeline; isso significa que o shell colocará as tarefas em segundo plano. A chamada para wait
então aguarda a conclusão de todas as tarefas em segundo plano. Ambos os processos terminarão aproximadamente ao mesmo tempo.
Esteja ciente de que, se um de seus processos for substancialmente mais lento, ele poderá tornar tudo significativamente mais lento, pois tee
poderá bloquear o canal stdout ou o canal nomeado no qual ele está gravando.Editar: Além disso, agora tem mais modos de falha, já que o tee sairá devido a um tubo quebrado se o seu processo secundário falhar.