Мы добавили file:
поддержку для StandardOutput и StandardError в версии 236.(https://github.com/systemd/systemd/pull/7198)--Боюсь, ваша версия устарела.
Разумным обходным решением в вашей версии было бы создание скрипта-оболочки, который настраивает stdout и stderr по вашему вкусу, и вместо этого вызывает его.
Предполагая, что это какой-то сценарий оболочки, поместите его вверху:
export MYPID=$$
(
flock 9
mkdir -p.started-pids
find.started-pids/ -type f ! -newermt '-2 seconds' -delete
n=`find.started-pids/ -type f | wc -l`
sleep $n
sleep $n
touch.started-pids/$MYPID
) 9>.lockfile
Это не довольно точно --иногда оно будет задерживать немного больше , чем должно, но не меньше, так что вашего всплеска не произойдет.
Измените имена каталогов lockfile и pid count на любые, которые вам нравятся.
Таким образом, это делается для того, чтобы избежать всплесков использования дисковых/сетевых или других ресурсов, когда несколько экземпляров запускаются одновременно. По крайней мере, для первых N из них вам нужен фиксированный интервал в X секунд.
Простой обходной путь — интерполировать дополнительный xargs
для задержки аргументов. Вот так:
find. -type f -print0 |
xargs -0 -n1 -P1 sh -c 'sleep 2; printf "%s\0" "$0"' |
xargs -0 -n1 -P4 sh do_something.sh
В приведенном выше примере у меня N=4 и интервал 2 секунды. Для первых N аргументов будет сохранен интервал. Затем, в случае, если некоторые выполнения заканчиваются близко, он может начать выполнение ближе по времени, и это то, что вы запрашиваете в этом комментарии .
Я также предполагал, что время казней будет не маленькое, а несколько секунд или больше. Также вы можете установить немного более высокую задержку, если вы все еще видите всплески для следующих исполнений. Основное узкое место в начале избегается.
Вот некоторые базовые тесты. Сценарий обработки do_something.sh
занимает произвольное время от 10 до 20 секунд.
> cat do_something.sh
printf "%s START processing %s\n" "$(date +"%H:%M:%S")" "$1"
sleep $(shuf -i10-20 -n1)
printf "%s END processing %s\n" "$(date +"%H:%M:%S")" "$1"
> touch file{1..10}
> find. -type f -name 'file*' -print0 |
> xargs -0 -n1 -P1 sh -c 'sleep 2; printf "%s\0" "$0"' |
> xargs -0 -n1 -P4 sh do_something.sh
02:03:22 START processing./file6
02:03:24 START processing./file9
02:03:26 START processing./file8
02:03:28 START processing./file2
02:03:38 END processing./file8
02:03:38 START processing./file7
02:03:40 END processing./file6
02:03:40 START processing./file1
02:03:41 END processing./file9
02:03:41 START processing./file3
02:03:45 END processing./file2
02:03:45 START processing./file4
02:03:55 END processing./file3
02:03:55 END processing./file7
02:03:55 START processing./file10
02:03:55 START processing./file5
02:04:00 END processing./file1
02:04:02 END processing./file4
02:04:05 END processing./file10
02:04:13 END processing./file5