Несоответствие протокола готовности. Вы сказали systemd, что ваша программа разветвляет дочерний процесс, а затем выходит из родительского процесса, чтобы сигнализировать о том, что он готов. Но на самом деле ваша программа этого не делает. Поскольку не указано, что он будет готов в течение 90 секунд (тайм-аут запуска по умолчанию), systemd решил, что ваша служба не работает. Неудачные службы убивают все. Из-за при сбое
ваша отказавшая служба затем перезапускается, и цикл повторяется.
Используйте протокол готовности, который правильно описывает, что на самом деле делает ваша программа. Этого вы нам не сказали.
Это не ответ на поставленный вопрос, а лишь отступление, показывающее, что предпосылка исходного вопроса, что "временный файл ... должен быть удален вручную", совершенно неверна.
(Я опубликовал этот "ответ" в том случае, если заметить, что эта предпосылка ложна, позволит ОП и другим людям не стесняться использовать временные файлы. Во многих случаях использование временных файлов делает скрипты более надежными и более простыми в сопровождении.)
Если скрипту Bash необходимо использовать один или несколько временных файлов, я всегда использую следующий подход:
#!/bin/bash
work="$(mktemp -d)" || exit 1
trap "cd / ; rm -rf '$work'" EXIT
Здесь используется помощник mktemp
для создания временного рабочего каталога (в /tmp/
). Если mktemp
недоступен или каталог не может быть создан, сценарий прерывается.
Чтобы автоматически удалить рабочий каталог и все файлы, которые он может содержать, мы устанавливаем ловушку EXIT
. Эта ловушка срабатывает - то есть bash выполняет указанную команду - всякий раз, когда shell завершает работу; будь то обычный выход или из-за ошибки.
Команда EXIT
trap переходит в корневой каталог (просто чтобы убедиться, что текущий рабочий каталог не находится во временном каталоге), а затем удаляет все поддерево. Обратите внимание, что поскольку команда заключена в двойные кавычки, $work
оценивается при установке ловушки; это означает, что даже если вы измените значение переменной work
позже в сценарии, ловушка все равно удалит исходный временный каталог.
Хотя ловушка изменяет текущий рабочий каталог, это не будет иметь никакого эффекта за пределами ловушки - ни в сценарии в другом месте, ни для других процессов - потому что текущий рабочий каталог специфичен для каждого процесса, а текущий процесс bash завершится сразу после выполнения команды ловушки.
Поэтому любые временные файлы, созданные под $work
, например "$work/1"
, "$work/result"
и так далее, автоматически удаляются, как и сам временный каталог $work
, после завершения работы скрипта.
Из первоначального запроса я понимаю, что вам нужно объединить 3 изображения (1 из файла и 2 сгенерированных) в один снимок, учитывая, что вы можете одновременно работать только с 2.
Я также понимаю, что вам не нужно хранить временные данные на диске. Самым быстрым решением было бы использовать tmpfs, как было предложено в предыдущем ответе @ nominal-animal.
Но если пойти дальше, можно избежать создания временных файлов и в основном выполнять всю обработку за один раз. Решение, которое я нашел, заключается в использовании "именованных каналов", это специальные файлы, которые не хранят данные на диске и даже приостанавливают любую передачу по каналам, пока принимающая часть также не будет готова. Я не буду использовать полную Команды, которые вы указали (только команда, ввод и вывод), не стесняйтесь вводить необходимые аргументы.
# First it's necessary to have the pipes created, one time operation and they can be reused over and over.
mknod /tmp/pipe1 p
mknod /tmp/pipe2 p
mknod /tmp/pipe3 p
# generate the 2 images and send each to a pipe
gm convert ... miff:- > pipe1 &
gm convert ... miff:- > pipe2 &
# merge the source image to the 1st generated image
gm composite ... source.tif pipe1 miff:- > pipe3 &
# finally merge the result to the 2nd generated image
gm composite ... pipe3 pipe2 out.tif
Похоже, что операция выполняется в 4 этапа, но на самом деле все будет выполнено за один раз без записи на диск.
Вот как это работает и почему команды написаны так, как они есть:
Вы можете рассматривать каналы как временные файлы, которые не являются файлами, просто не забудьте поместить некоторые вещи в фоновый режим, иначе сценарий будет ждать вашего CTRL + C. Каждую команду нужно ставить в фоновый режим отдельно! Нет проблем, если вы поместите их в сценарий, подобный этому, после того, как сгенерированы выходные данные, до которых завершились предыдущие команды.
Приятной особенностью является то, что вы можете запускать любые 3 команды сначала в фоновом режиме, а последнюю - в обычном режиме, поскольку все 4 зависят от данных из каналов. Также его легко расширить на несколько команд, просто добавив больше каналов.
Есть одно ограничение, которое я вижу, вы не можете использовать одни и те же каналы параллельно, если вам нужно, вы должны использовать разные наборы каналов для каждого экземпляра, работающего параллельно, иначе будут сюрпризы :) {{1 }} Последовательная обработка не имеет такой проблемы.
С точки зрения производительности, я не знаю, быстрее ли это, чем создание временных файлов в "tmpfs", поэтому вам нужно будет выяснить это путем тестирования в реальном сценарии. Чтобы это сработало, вы должны иметь достаточно памяти для размещения всех 4 процессов с их данными в памяти. (это во многом зависит от размера изображений, которые вы обрабатываете / генерируете).