Как остановить скрипт в определенное время, пока cron не запустит его снова?

12

У меня Raspberry Pi работает OSMC (на основе Debian).

Я установил задание cron для запуска скрипта sync.sh в полночь.

0 0 * * * /usr/local/bin sync.sh

Мне нужно остановить сценарий в 7 утра. В настоящее время я использую:

0 7 * * * shutdown -r now

Есть ли способ лучше? Я чувствую, что перезагрузка - это перебор.

Благодарность

Энтони
источник

Ответы:

25

Вы можете запустить его с помощью timeoutкоманды ,

timeout - run a command with a time limit

Synopsis
timeout [OPTION] NUMBER[SUFFIX] COMMAND [ARG]...
timeout [OPTION]
Description

Start COMMAND, and kill it if still running after NUMBER seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days. 

PS. Если процесс синхронизации занимает слишком много времени, вы можете рассмотреть другой подход к синхронизации данных, возможно, заблокировать репликацию.

Рабин
источник
У меня медленное интернет-соединение, поэтому синхронизация занимает так много времени. Вы бы порекомендовали какой-либо конкретный сигнал?
Энтони
@ Энтони, как ты сейчас синхронизируешься?
Рабин
lftp.tech
Энтони
Более конкретно: gist.github.com/feralhosting/4e7e93a7fecd8f55cb4a
Энтони
@ Энтони, вы можете попробовать другое приложение, такое как syncthing ( syncthing.net ) или BTSync ( resilio.com ), которые работают на уровне блоков файла для синхронизации
Рабин
9

Если ваша синхронизация может легко продолжаться после 17 часов гибернации, попробуйте

0 0 * * * killall -CONT -g sync.sh || /usr/local/bin/sync.sh
7 0 * * * killall -STOP -g sync.sh

Если ваша синхронизация предпочитает перезапускаться с самого начала, попробуйте

0 0 * * * exec /usr/local/bin/sync.sh
7 0 * * * killall -TERM -g sync.sh

Если ваша синхронизация или ее подзадачи игнорируют сигналы, но не оставляют мусора, сделайте это

0 0 * * * exec /usr/local/bin/sync.sh
7 0 * * * killall -KILL -g sync.sh

killallpsmisc

Роман Чиборра
источник
Я использую скрипт, показанный ниже, с зеркалом -c, похоже, он не против перезапуска. Что из вышеперечисленного вы бы порекомендовали ?: gist.github.com/feralhosting/4e7e93a7fecd8f55cb4a
Энтони
Видя, что сценарий LFTP хочет, чтобы SIGTERM очистил свой файл блокировки, и рассматривая вероятность истечения времени ожидания сервера на 17 часов простоя или даже худшего перенумерации inet [64], я бы выбрал 0 0 * * * timeout 7h /usr/local/bin/sync.shили мой в основном эквивалентный killall -TERMвариант.
Роман Чиборра
4

Я бы также использовал cron, чтобы «остановить» или «убить» этот сервис или скрипт в указанное время.
Сначала создайте задание cron для запуска задания или сценария. (вы можете легко запустить другой cron, который убьет задание с именем sudo pkill wget)

Во-вторых, вы хотите видеть запущенные задачи crontab в удобном и читаемом формате в выводе:

   ps -o pid,sess,cmd afx | egrep "( |/)cron( -f)?$"

Они появятся в первых строках, примерно так:

1108  1108 cron
4288  1108 \_ CRON
4289  4289     \_ /bin/sh -c /path/to/my/crontab/script1.sh
4290  4289         \_ /bin/bash /path/to/my/crontab/script1.sh
4295  4289             \_ /usr/bin/wget LINK

Первый столбец - PID, второй - Session ID, а третий - команда, запущенная cron. Вы можете уничтожить все процессы, связанные с конкретной задачей cron, используя идентификатор сессии, поэтому в приведенном выше примере вы должны уничтожить идентификатор сессии 4289:

   pkill -s 4289

Вы должны поместить pkill в скрипт и запустить его как cron

ddlingo
источник
Будет ли идентификатор сессии меняться при каждом запуске задания cron? Как насчет после выключения и включения?
Энтони
да, это изменится. Но если вы запишете его, вы можете получить PID и поместить его в переменную. Вы можете просто использовать имя, если оно появляется. pkill sync.sh
ddlingo