У вас есть */30
в спецификаторе минут - это означает каждую минуту, но с шагом 30 (другими словами, каждые полчаса). Так cron
как не доходит до субминутных разрешений, вам нужно будет найти другой путь.
Одна из возможностей, хотя и немного сложная (а) , состоит в том, чтобы иметь два задания, одно из которых смещено на 30 секунд:
# Need these to run on 30-sec boundaries, keep commands in sync.
* * * * * /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )
Вы увидите, что я добавил комментарии и отформатировал их, чтобы их было легко синхронизировать.
Обе cron
работы фактически выполняются каждую минуту, но последняя будет ждать полминуты, прежде чем выполнять «мясо» задания /path/to/executable
.
Для других (не cron
основанных) вариантов смотрите другие ответы здесь, особенно те, которые упоминают fcron
и systemd
. Это, вероятно, предпочтительнее, если ваша система может их использовать (например, установка fcron
или наличие дистрибутива systemd
).
Если вы не хотите использовать решение kludgy, вы можете использовать решение на основе цикла с небольшой модификацией. Вам все равно придется управлять тем, чтобы ваш процесс работал в какой-то форме, но после сортировки должен работать следующий скрипт:
#!/bin/env bash
# Debug code to start on minute boundary and to
# gradually increase maximum payload duration to
# see what happens when the payload exceeds 30 seconds.
((maxtime = 20))
while [[ "$(date +%S)" != "00" ]]; do true; done
while true; do
# Start a background timer BEFORE the payload runs.
sleep 30 &
# Execute the payload, some random duration up to the limit.
# Extra blank line if excess payload.
((delay = RANDOM % maxtime + 1))
((maxtime += 1))
echo "$(date) Sleeping for ${delay} seconds (max ${maxtime})."
[[ ${delay} -gt 30 ]] && echo
sleep ${delay}
# Wait for timer to finish before next cycle.
wait
done
Хитрость заключается в том, чтобы использовать его, sleep 30
но запускать его в фоновом режиме до запуска полезной нагрузки. Затем, после того, как полезная нагрузка закончена, просто подождите, пока sleep
закончится фон .
Если полезная нагрузка занимает n
секунды (где n <= 30
), ожидание после полезной нагрузки будет 30 - n
секундами. Если это займет более 30 секунд, то следующий цикл будет отложен до завершения полезной нагрузки, но не дольше.
Вы увидите, что у меня есть отладочный код, который начинается на минутной границе, чтобы на выходе было легче следовать. Я также постепенно увеличиваю максимальное время полезной нагрузки, так что вы в конечном итоге увидите, что полезная нагрузка превышает 30-секундное время цикла (выводится дополнительная пустая строка, поэтому эффект очевиден).
Далее следует примерный цикл (где циклы обычно начинаются через 30 секунд после предыдущего цикла):
Tue May 26 20:56:00 AWST 2020 Sleeping for 9 seconds (max 21).
Tue May 26 20:56:30 AWST 2020 Sleeping for 19 seconds (max 22).
Tue May 26 20:57:00 AWST 2020 Sleeping for 9 seconds (max 23).
Tue May 26 20:57:30 AWST 2020 Sleeping for 7 seconds (max 24).
Tue May 26 20:58:00 AWST 2020 Sleeping for 2 seconds (max 25).
Tue May 26 20:58:30 AWST 2020 Sleeping for 8 seconds (max 26).
Tue May 26 20:59:00 AWST 2020 Sleeping for 20 seconds (max 27).
Tue May 26 20:59:30 AWST 2020 Sleeping for 25 seconds (max 28).
Tue May 26 21:00:00 AWST 2020 Sleeping for 5 seconds (max 29).
Tue May 26 21:00:30 AWST 2020 Sleeping for 6 seconds (max 30).
Tue May 26 21:01:00 AWST 2020 Sleeping for 27 seconds (max 31).
Tue May 26 21:01:30 AWST 2020 Sleeping for 25 seconds (max 32).
Tue May 26 21:02:00 AWST 2020 Sleeping for 15 seconds (max 33).
Tue May 26 21:02:30 AWST 2020 Sleeping for 10 seconds (max 34).
Tue May 26 21:03:00 AWST 2020 Sleeping for 5 seconds (max 35).
Tue May 26 21:03:30 AWST 2020 Sleeping for 35 seconds (max 36).
Tue May 26 21:04:05 AWST 2020 Sleeping for 2 seconds (max 37).
Tue May 26 21:04:35 AWST 2020 Sleeping for 20 seconds (max 38).
Tue May 26 21:05:05 AWST 2020 Sleeping for 22 seconds (max 39).
Tue May 26 21:05:35 AWST 2020 Sleeping for 18 seconds (max 40).
Tue May 26 21:06:05 AWST 2020 Sleeping for 33 seconds (max 41).
Tue May 26 21:06:38 AWST 2020 Sleeping for 31 seconds (max 42).
Tue May 26 21:07:09 AWST 2020 Sleeping for 6 seconds (max 43).
Если вы хотите избежать грязного решения, это, вероятно, лучше. Вам все еще понадобится cron
задание (или его эквивалент), чтобы периодически обнаруживать, работает ли этот сценарий, и, если нет, запускать его. Но сам скрипт обрабатывает время.
(а) Некоторые мои коллеги сказали бы, что моя специальность - это кладжи :-)