5

Как автоматически создать cron-задачу с помощью Bash без интерактивного редактора?

13

Существует ли возможность в crontab создать задания Cron без использования редактора (crontab -e)? Если да, то каков будет код для создания задания Cron из Bash-скрипта?

5 ответ(ов)

4

Вы можете сделать это на лету:

crontab -l | { cat; echo "0 0 0 0 0 some entry"; } | crontab -

Этот подход работает, поскольку команда crontab -l выводит текущие задания crontab, cat выводит их (из стандартного ввода), echo добавляет новую команду, а crontab - записывает все напечатанное в файл crontab. Чтобы увидеть изменения, просто выполните команду crontab -l снова.

Обратите внимание: если у пользователя нет существующего crontab, вы можете увидеть следующее сообщение:

no crontab for <username>

Тем не менее, это по-прежнему работает, даже если вы видите это сообщение.

1

Этот более короткий способ не требует временного файла, не подвержен множественным вставкам и позволяет менять расписание уже существующей записи.

Допустим, у вас есть следующие команды:

croncmd="/home/me/myfunction myargs > /home/me/myfunction.log 2>&1"
cronjob="0 */15 * * * $croncmd"

Чтобы добавить это в crontab, без дублирования:

( crontab -l | grep -v -F "$croncmd" ; echo "$cronjob" ) | crontab -

Чтобы удалить это из crontab, независимо от его текущего расписания:

( crontab -l | grep -v -F "$croncmd" ) | crontab -

Примечания:

  • grep -F выполняет поиск строки в буквальном значении, поскольку мы не хотим интерпретировать её как регулярное выражение.
  • Мы также игнорируем временные расписания и только смотрим на саму команду. Таким образом, расписание можно изменить без риска добавления новой строки в crontab.
0

Спасибо всем за помощь. Собрав информацию здесь и там, я пришел к следующему решению:

Код

command="php $INSTALL/indefero/scripts/gitcron.php"
job="0 0 * * 0 $command"
cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -

Я не смог понять, как избавиться от необходимости в двух переменных, не повторяя код.

command — это, очевидно, команда, которую я хочу запланировать. job берет $command и добавляет к нему данные о расписании. Мне нужны обе переменные отдельно в строке кода, выполняющей работу.

Подробности

  1. Благодарность duckyflip — я использую этот маленький редирект (<(*command*)), чтобы превратить вывод crontab -l в ввод для команды fgrep.
  2. Затем fgrep фильтрует все совпадения с $command (опция -v), игнорируя регистр (опция -i).
  3. Снова используется маленький редирект (<(*command*)), чтобы вернуть результат в ввод для команды cat.
  4. Команда cat также получает echo "$job" (это и так понятно), вновь через использование редиректа (<(*command*)).
  5. Таким образом, отфильтрованный вывод из crontab -l и простое echo "$job", в совокупности, передаются ('|') в crontab -, чтобы в итоге записаться.
  6. И они все жили долго и счастливо!

В двух словах:

Эта строка кода фильтрует любые задания cron, которые совпадают с командой, затем записывает оставшиеся задания cron с новым, что фактически действует как функция "добавить" или "обновить". Чтобы воспользоваться этим, вам достаточно заменить значения переменных command и job.

0

Используя команду cat с подстановочными файлами, вы можете добавить новую задачу в crontab, не перезаписывая существующие задачи. Вот исправленный вариант, который решает проблему с перезаписью:

cat <(crontab -l) <(echo "1 2 3 4 5 scripty.sh") | crontab -

В этом примере crontab -l выводит существующие задачи расписания, а echo добавляет новую задачу scripty.sh, которая будет выполняться в указанные время. Затем объединенные результаты передаются в crontab -, чтобы обновить расписание. Обратите внимание, что этот метод работает, если вы хотите добавить только одну задачу, не удаляя текущие.

0

На StackOverflow было много хороших ответов по использованию crontab, но не упомянута более простая методика с использованием cron.

Использование cron позволяет воспользоваться системными файлами и директориями, расположенными по путям /etc/crontab, /etc/cron.daily, /etc/cron.weekly, /etc/cron.hourly и /etc/cron.d/:

cat > /etc/cron.d/<job> << EOF
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root HOME=/
01 * * * * <user> <command>
EOF

В этом примере мы создаем файл в /etc/cron.d/, указываем переменные среды для успешного выполнения команды, а также пользователя и саму команду. Этот файл не должен быть исполняемым, и его имя должно содержать только буквы, цифры и дефисы (подробности ниже).

Чтобы ответ был более полным, давайте рассмотрим различия между crontab и cron/crond:

crontab -- поддержка таблиц для запуска cron для отдельных пользователей

Для тех, кто хочет запускать задания от имени своего пользователя в системе, использование crontab может быть разумным выбором.

cron -- демон для выполнения запланированных команд

Для тех, кто использует управление конфигурацией или хочет управлять заданиями для других пользователей, в этом случае стоит использовать cron.

Небольшой отрывок из man-страниц дает несколько примеров того, что можно и чего нельзя делать:

/etc/crontab и файлы в /etc/cron.d должны принадлежать пользователю root и не должны иметь разрешения на запись для группы или других пользователей. В отличие от области очереди, файлы в /etc/cron.d или файлы в /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly и /etc/cron.monthly могут также быть символическими ссылками, при условии, что и ссылка, и файл, на который она указывает, принадлежат пользователю root. Файлы в /etc/cron.d не требуют исполняемых прав, в то время как файлы в /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly и /etc/cron.monthly должны быть исполняемыми, так как они запускаются с помощью run-parts (см. run-parts(8) для получения дополнительной информации).

Источник: http://manpages.ubuntu.com/manpages/trusty/man8/cron.8.html

Управление cron таким образом проще и более масштабируемо с точки зрения системы, однако это не всегда будет лучшим решением.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь