Published by @squadette on 2018-02-02
Стандартная задача — есть поток входящих файлов, на их основе надо создавать результирующие файлы. Входящих файлов десятки и сотни, постоянно появляются новые. Процессоров на машине много. Хочется сделать просто, надежно, с использованием всех процессоров и с минимальными усилиями. Неоднократно оказывалось, что хорошим инструментом для решения этой задачи может стать старый добрый GNU Make.
Например, у нас есть поток видео-файлов в формате .ts
. Из каждого такого файла надо создать а) файл для iPad б) файл для Flash в) промежуточный WAV-файл г) файл с аудио-отпечатком и д) залить аудио-отпечаток на удаленный сервер.
Можно создать Makefile, который будет выглядеть примерно так:
.PHONY: all
all: file1.afp-uploaded file1.mp4 file1.flv
file1.mp4: file1.ts
convert-to-mp4.sh $< $@
file1.flv: file1.ts
convert-to-mp4.sh $< $@
file1.wav: file1.ts
convert-to-wav.sh $< $@
file1.afp: file1.wav
generate-audio-fingerprint.sh $< $@
file1.afp-uploaded: file1.afp
scp $< 192.168.1.1:
touch $@
Теперь скажем make -j 3 all
. На основании информации о зависимости файлов и инструкции по их созданию Make начнет запускать указанные скрипты. Ключ -j 3
означает, что в каждый момент времени будет запущено вплоть до трех одновременных задач (если есть возможность для распараллеливания). Естественно, цифру нужно подобрать в соответствии с возможностями вашего железа.
Так, в нашем примере будут параллельно генерироваться file1.mp4
, file1.flv
и file1.wav
. Сразу после генерации file1.wav
(на фоне прочих выполняющихся задач) начнет генерироваться file1.afp
. Если требуется выполнить задачу, не связанную с созданием файла — например, залить файл на удаленный сервер, то используется стандартный трюк с пустым файлом (в данном случае file1.afp-uploaded
). Переменная $<
означает “входной файл”, переменная $@
— выходной файл.
Это был пример. Так как файлов много, то давайте напишем скрипт, который берет список новых пришедших файлов, генерирует Makefile
, а затем запускает make
, который волшебным образом обработает всю простыню. Затем обработанные файлы можно удалить, снова сгенерировать Makefile
и повторять до бесконечности.
Язык GNU Make подробно описан в документации и местами довольно непрост из-за того, что в нем перемешаны команды shell и конструкции самого Makefile. Иногда в сложных случаях можно запутаться в знаках доллара и т. п. Однако, если просто генерировать Makefile
внешними средствами, без использования макро-команд Make, то обычно никаких проблем не возникает.