it-roy-ru.com

Запуск cron каждые 30 секунд

Итак, у меня есть хрон, который мне нужно запускать каждые 30 секунд.

Вот что у меня есть:

*/30 * * * * /bin/bash -l -c 'cd /srv/last_song/releases/20120308133159 && script/Rails runner -e production '\''Song.insert_latest'\'''

Он работает, но работает ли он каждые 30 минут или 30 секунд?

Кроме того, я читал, что Cron может быть не лучшим инструментом для использования, если я запускаю его так часто. Есть ли другой лучший инструмент, который я могу использовать или установить на Ubuntu 11.04, который будет лучшим вариантом? Есть ли способ исправить вышеуказанный cron?

242
Matt Elhotiby

У вас есть */30 в спецификаторе minutes - это означает каждую минуту, но с шагом 30 (другими словами, каждые полчаса). Поскольку cron не сводится к субминутным разрешениям, вам нужно будет найти другой путь.

Одна из возможностей, хотя и немного сложная, состоит в том, чтобы иметь два задания, одно смещение на 30 секунд:

* * * * * /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )

Оба cron задания на самом деле запускаются каждую минуту, но последний будет ждать полминуты, прежде чем выполнять «мясо» задания, /path/to/executable.

580
paxdiablo

Ты не можешь Cron имеет 60-секундную зернистость.

* * * * * cd /srv/last_song/releases/20120308133159 && script/Rails runner -e production '\''Song.insert_latest'\''
* * * * * sleep 30 && cd /srv/last_song/releases/20120308133159 && script/Rails runner -e production '\''Song.insert_latest'\''
53
wildplasser

Детализация Крона в минутах и ​​ не была предназначена для пробуждения каждые x секунд, чтобы что-то запустить. Запустите повторяющуюся задачу в цикле, и она должна делать то, что вам нужно:

#!/bin/env bash
while [ true ]; do
 sleep 30
 # do what you need to here
done
35
Marvin Pinto

Нет необходимости в двух записях cron, вы можете поместить их в одну с помощью:

* * * * * /bin/bash -l -c "/path/to/executable; sleep 30 ; /path/to/executable"

так в вашем случае:

* * * * * /bin/bash -l -c "cd /srv/last_song/releases/20120308133159 && script/Rails runner -e production '\''Song.insert_latest'\'' ; sleep 30 ; cd /srv/last_song/releases/20120308133159 && script/Rails runner -e production '\''Song.insert_latest'\''"

22
Andrew

Вы можете проверить мой ответ на этот похожий вопрос

По сути, я включил туда bash-скрипт с именем «runEvery.sh», который вы можете запускать с помощью cron каждую 1 минуту и ​​передавать в качестве аргументов реальную команду, которую вы хотите запустить, и частоту в секундах, с которой вы хотите ее запускать.

что-то вроде этого

* * * * * ~/bin/runEvery.sh 5 myScript.sh

11
shlomia

Задание Cron нельзя использовать для планирования задания с интервалом в несколько секунд. Т.е. вы не можете запланировать запуск задания cron каждые 5 секунд. Альтернативой является написание сценария оболочки, в котором используется команда sleep 5.

Создайте скрипт Shell каждые 5-seconds.sh, используя цикл bash while, как показано ниже.

$ cat every-5-seconds.sh
#!/bin/bash
while true
do
 /home/ramesh/backup.sh
 sleep 5
done

Теперь выполните этот сценарий оболочки в фоновом режиме, используя Nohup, как показано ниже. Это продолжит выполнение сценария даже после выхода из сеанса. Это будет запускать скрипт резервного копирования backup.sh каждые 5 секунд.

$ Nohup ./every-5-seconds.sh &
9
Pankaj Shinde

Используйте часы:

$ watch --interval .30 script_to_run_every_30_sec.sh
7
user7079817

в директории /etc/cron.d/

новый создать файл excute_per_30s

* * * * * yourusername  /bin/date >> /home/yourusername/temp/date.txt
* * * * * yourusername sleep 30; /bin/date >> /home/yourusername/temp/date.txt

будет запускать cron каждые 30 секунд

6
LingYFH

Использовать fcron ( http://fcron.free.fr/ ) - дает вам детализацию в считанные секунды и намного лучше и более функционально, чем cron (vixie-cron) и стабильную. Раньше я делал глупости, например, когда на одной машине работало около 60 php-скриптов в очень дурацких настройках, и это все еще выполняло свою работу!

5
Adi Chiru

Если вы используете новейшую ОС Linux с SystemD, вы можете использовать модуль таймера SystemD для запуска вашего скрипта на любом уровне детализации, который вы пожелаете (теоретически до наносекунд), и - если вы хотите - гораздо более гибкие правила запуска, чем когда-либо допускал Cron. , Нет sleep требуется кладж

Для настройки требуется немного больше, чем для отдельной строки в файле cron, но если вам нужно что-то лучше, чем «Каждую минуту», оно того стоит.

Модель таймера SystemD в основном такова: таймеры - это единицы, которые запускают единицы обслуживания по истечении таймера.

Таким образом, для каждого сценария/команды, которую вы хотите запланировать, у вас должен быть блок обслуживания, а затем дополнительный блок таймера. Один таймер может включать в себя несколько расписаний, поэтому обычно вам не требуется более одного таймера и одного сервиса.

Вот простой пример, который регистрирует «Hello World» каждые 10 секунд:

/etc/systemd/system/helloworld.service:

[Unit]
Description=Say Hello
[Service]
ExecStart=/usr/bin/logger -i Hello World

/etc/systemd/system/helloworld.timer:

[Unit]
Description=Say Hello every 10 seconds
[Timer]
OnBootSec=10
OnUnitActiveSec=10
AccuracySec=1ms
[Install]
WantedBy=timers.target

После настройки этих устройств (в /etc/systemd/system, как описано выше, для общесистемной настройки или в ~/.config/systemd/user для пользовательской настройки), вам нужно включить таймер (но не службу), запустив systemctl enable helloworld.timer. Если вы хотите запустить таймер немедленно (вместо ожидания его запуска после перезагрузки), также запустите systemctl start helloworld.timer.

Здесь используются поля секции [Timer]:

  • OnBootSec - запускать службу через много секунд после каждой загрузки.
  • OnUnitActiveSec - запустить службу через много секунд после последнего запуска службы. Это то, что заставляет таймер повторяться и вести себя как задание cron.
  • AccuracySec - устанавливает точность таймера. Таймеры имеют такую ​​же точность, как это поле, и по умолчанию используется 1 минута (имитирует cron). Основная причина не требовать максимальной точности заключается в повышении энергопотребления - если SystemD может запланировать следующий запуск так, чтобы он совпадал с другими событиями, он должен реже разбудить ЦП. 1ms в вышеприведенном примере не идеален - я обычно устанавливаю точность 1 (1 секунда) в моих подминутных запланированных заданиях, но это будет означать, что если вы посмотрите журнал, показывающий сообщения «Hello World», вы вижу, что часто бывает поздно на 1 секунду. Если вы согласны с этим, я предлагаю установить точность до 1 секунды или более.

Как вы, возможно, заметили, этот таймер не очень хорошо имитирует Cron - в том смысле, что команда не запускается в начале каждого периода настенных часов (т.е. она не запускается на 10-й секунде на часах, потом 20 и тд). Вместо этого просто происходит, когда таймер истекает. Если система загрузилась в 12:05:37, то в следующий раз команда будет запущена в 12:05:47, затем в 12:05:57 и т.д. Если вас интересует фактическая точность настенных часов, вы можете хотите заменить поля OnBootSec и OnUnitActiveSec и вместо этого установить правило OnCalendar с нужным вам расписанием (которое, насколько я понимаю, не может быть быстрее, чем 1 секунда при использовании формата календаря). Приведенный выше пример также можно записать так:

OnCalendar=*-*-* *:*:00,10,20,30,40,50

Последнее замечание: как вы, наверное, догадались, модуль helloworld.timer запускает модуль helloworld.service, потому что они имеют одинаковое имя (за исключением суффикса типа модуля). Это значение по умолчанию, но вы можете переопределить его, установив поле Unit для раздела [Timer].

Более подробную информацию можно найти по адресу:

4
Guss

Задание Crontab можно использовать для планирования задания в минутах/часах/днях, но не в секундах. Альтернатива:

Создайте скрипт для выполнения каждые 30 секунд:

#!/bin/bash
# 30sec.sh

for COUNT in `seq 29` ; do
  cp /application/tmp/* /home/test
  sleep 30
done

Используйте crontab -e и crontab для выполнения этого скрипта:

* * * * * /home/test/30sec.sh > /dev/null
4
szaier

Спасибо за все хорошие ответы. Для простоты мне понравилось смешанное решение с управлением crontab и разделением времени в скрипте. Вот что я сделал для запуска сценария каждые 20 секунд (три раза в минуту). Линия Crontab: 

 * * * * 1-6 ./a/b/checkAgendaScript >> /home/a/b/cronlogs/checkAgenda.log

Автор сценария: 

cd /home/a/b/checkAgenda

Java -jar checkAgenda.jar
sleep 20
Java -jar checkAgenda.jar 
sleep 20
Java -jar checkAgenda.jar 
1
jfajunior

У меня просто была похожая задача, и я использовал следующий подход: 

Nohup watch -n30 "kill -3 NODE_PID" &

Мне нужно было периодически убивать -3 (чтобы получить трассировку стека программы) каждые 30 секунд в течение нескольких часов.

Nohup ... & 

Это здесь, чтобы быть уверенным, что я не потеряю выполнение наблюдения, если потеряю оболочку (проблема с сетью, сбой Windows и т.д.)

0
Thomas

написать один сценарий оболочки создать .sh файл

nano every30second.sh

и написать сценарий

#!/bin/bash
For  (( i=1; i <= 2; i++ ))
do
    write Command here
    sleep 30
done

затем установите cron для этого скрипта crontab -e

(* * * * * /home/username/every30second.sh)

этот файл cron вызывает файл .sh каждые 1 минуту и ​​в команде .sh file запускается 2 раза за 1 минуту 

если вы хотите запустить скрипт в течение 5 секунд, замените 30 на 5 и измените цикл следующим образом: For (( i=1; i <= 12; i++ ))

когда вы выбираете для любой секунды, затем рассчитать 60/свою секунду и написать в цикле For

0
Aditya Gosavi

В настоящее время я использую метод ниже. Работает без проблем.

* * * * * /bin/bash -c ' for i in {1..X}; do YOUR_COMMANDS ; sleep Y ; done '

Если вы хотите запускать каждыеNсекунды, тоXбудет 60/N иYбудетN.

Спасибо.

0
sujoshi