Как создать работу cron с помощью Bash автоматически без интерактивного редактора? - PullRequest
334 голосов
/ 18 мая 2009

Есть ли у crontab аргумент для создания заданий cron без использования редактора (crontab -e). Если так, какой код создаст cronjob из скрипта Bash?

Ответы [ 19 ]

477 голосов
/ 18 мая 2009

Вы можете добавить в crontab следующее:

#write out current crontab
crontab -l > mycron
#echo new cron into cron file
echo "00 09 * * 1-5 echo hello" >> mycron
#install new cron file
crontab mycron
rm mycron

объяснение линии Cron

* * * * * "command to be executed"
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)

Источник nixCraft .

284 голосов
/ 18 мая 2009

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

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

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

66 голосов
/ 31 июля 2013

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

Скажем, у вас есть эти:

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
38 голосов
/ 12 ноября 2011

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

Код

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.

24 голосов
/ 18 мая 2009

РЕДАКТИРОВАТЬ (исправлена ​​перезапись):

cat <(crontab -l) <(echo "1 2 3 4 5 scripty.sh") | crontab -
11 голосов
/ 14 марта 2017

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

Использование cron позволит использовать системные файлы и каталоги, расположенные в /etc/crontab, /etc/cron.daily,weekly,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/, предоставили переменные среды для успешного выполнения команды и предоставили user для команды и сам command. Этот файл не должен быть исполняемым, а имя должно содержать только буквенно-цифровые и дефисы (подробнее см. Ниже).

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

crontab -- maintain tables for driving cron for individual users

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

cron -- daemon to execute scheduled commands

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

Краткий отрывок из справочных страниц дает вам несколько примеров того, что нужно делать, а чего нет:

/ 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 делают это, как они запускаются частями выполнения (для получения дополнительной информации см. части выполнения (8)).

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

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

7 голосов
/ 19 июля 2010

Скорее всего, вы автоматизируете это, и вам не нужно добавлять ни одного задания дважды. В этом случае используйте:

__cron="1 2 3 4 5 /root/bin/backup.sh"
cat <(crontab -l) |grep -v "${__cron}" <(echo "${__cron}")

Это работает только если вы используете BASH. Мне неизвестен правильный синтаксис DASH (sh).

Обновление: Это не работает, если у пользователя еще нет crontab. Более надежный способ будет:

(crontab -l ; echo "1 2 3 4 5 /root/bin/backup.sh") | sort - | uniq - | crontab - 

В качестве альтернативы, если ваш дистрибутив поддерживает его, вы также можете использовать отдельный файл:

echo "1 2 3 4 5 /root/bin/backup.sh" |sudo tee /etc/crond.d/backup

Нашли те в другой вопрос SO .

5 голосов
/ 21 ноября 2015

Вариант, который редактирует crontab, только если там не найдена нужная строка:

CMD="/sbin/modprobe fcpci"
JOB="@reboot $CMD"
TMPC="mycron"
grep "$CMD" -q <(crontab -l) || (crontab -l>"$TMPC"; echo "$JOB">>"$TMPC"; crontab "$TMPC")
4 голосов
/ 29 мая 2014

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

crontab <<EOF
00 09 * * 1-5 echo hello
EOF
3 голосов
/ 23 мая 2009

Если вы используете Vixie Cron, например, в большинстве дистрибутивов Linux вы можете просто поместить файл в /etc/cron.d с отдельным cronjob.

Это работает только для root, конечно. Если ваша система поддерживает это, вы должны увидеть там несколько примеров. (Обратите внимание на имя пользователя, включенное в строку, в том же синтаксисе, что и старый / etc / crontab)

Это печальная ошибка в cron, что нет способа справиться с этим как обычного пользователя, и что так много реализаций cron вообще не имеют возможности справиться с этим.

...