
Иногда мне нужно вставить что-то в конвейер для отчетности или какого-то другого вторичного использования. Это может быть что-то простое, как wc -l
, или что-то более сложное, как awk
или даже скрипт на Python. Было бы неплохо запустить конвейер так:
zcat my_data_file.gz \
| wc -l > /tmp/linecount
| process_data.py
Проблема в том, что большинство утилит не выводят данные в stdout. tee
Можно записать данные во временный файл, но тогда придется ждать, пока все будет сделано:
zcat my_data_file.gz \
| tee /tmp/f \
| process_data.py && \
wc -l /tmp/f > /tmp/linecount && rm /tmp/f
Это не оптимально: это может быть очень длительный конвейер; я могу захотеть увидеть промежуточные результаты от аналога раньше wc
; и я могу не захотеть хранить все данные во временном файле.
решение1
Для этого можно использовать tee
и обрабатывать замену :>(...)
zcat my_data_file.gz |
# Count number of lines in stream
tee >(wc -l > /tmp/linecount) |
# Further processing
process_data.py
Обратите внимание, что для продолжения строк можно использовать каналы, а комментарии можно вставлять между командами, что является удобной функцией при построении сложных конвейеров.
решение2
Это не совсем эффективно, но вы можете этого добиться с помощьюименованные каналы, который вы можете создать с помощьюmkififo(1)
Для примера в вопросе:
mkfifo /tmp/f
wc -l /tmp/f > /tmp/linecount &
zcat my_data_file.gz \
| tee /tmp/f \
| process_data.py &
wait
rm /tmp/f
Обратите внимание на &
добавление к обоим wc
и конвейеру; это означает, что оболочка переведет задачи в фоновый режим. Затем вызов wait
ожидает завершения всех фоновых задач. Оба процесса завершатся примерно в одно и то же время.
Помните, что если один из ваших процессов работает существенно медленнее, это может существенно замедлить весь процесс, поскольку tee
может заблокировать либо его канал stdout, либо именованный канал, в который он записывает данные.Редактировать: Кроме того, теперь у него больше режимов отказа, так как тройник выйдет из строя из-за поломки трубы, если ваш вторичный процесс выйдет из строя.