Як створити кронтаб через сценарій


153

Мені потрібно додати завдання cron через скрипт, який я запускаю для налаштування сервера. Зараз я використовую Ubuntu. Я можу використовувати, crontab -eале це відкриє редактор для редагування поточного crontab. Я хочу це зробити програмно.

Чи можна це зробити?




Якщо ви хочете змінити або видалити запис із записом на кронтаб, див. Моє рішення нижче.
Брайан Сміт

Відповіді:


11

Завдання Cron зазвичай зберігаються у файлі користувача за адресою /var/spool/cron

Найпростіша для вас річ - це, мабуть, просто створити текстовий файл із налаштованим завданням, після чого скопіюйте його в папку col spool і переконайтеся, що він має правильні дозволи (600).


20
Змінення файлів безпосередньо в / var / spool / cron нахмуриться. Насправді, якщо ви подивитесь на файли там, вони, як правило, містять попередження, такі як "НЕ редагувати цей файл" як перший рядок.
Джаред

12
@Jred Хоча я цілком погоджуюся з цією ідеєю, мовляв, вона "нахмурена" не дуже допомагає. Скоріше скажіть, який ще файл слід редагувати, якщо такий є, або поясніть ризики редагування файлів вручну. Я планую створити кілька завдань на Cron за допомогою автоматизованого командного рядка, і якщо редагування цього файлу є єдиним варіантом, і без значних побічних ефектів, я не бачу, чому я не повинен його використовувати.
Бальміпур

47
Прокрутіть униз, щоб отримати справжню відповідь.
Джон Ред

1
На мій погляд, ця відповідь шлях краще: stackoverflow.com/a/610860/2681752
galaux

2
Я взяв такий підхід і пошкодував його. У RHEL каталог / var / spool / cron не виконується у всьому світі, тому користувачі не можуть переміщати каталог та редагувати свої файли вручну. Якщо ви зробите / var / spool / cron world виконуваним, ваш дружній місцевий sysadmin буде злий на вас, плюс зміна дозволу може бути перезаписана, якщо пакет кроні буде коли-небудь перевстановлений або оновлений.
functionvoid

384

Ось однофайл, який не використовує / не вимагає, щоб нове завдання було у файлі:

(crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -

Це 2>/dev/nullважливо, щоб ви не отримали no crontab for usernameповідомлення про те, що деякі * nixes виробляють, якщо в даний час немає записів на кронібках.


14
Це має бути прийнятою відповіддю. Просто зараз потрібен спосіб перевірити, чи вже є одне вкладише, яке я маю на меті додати
ChrisPrime

7
... Ой , зачекайте, ось як перевірити , якщо що - то в кронтаб мого користувача, перш ніж додати його за допомогою сценарію: stackoverflow.com/a/14451184/3686125
ChrisPrime

1
якщо цей скрипт призначений як команда для повторення та зміни існуючої задачі cron, було б непогано замінити існуючий рядок у crontab. декілька маркерів можуть бути використані для керування різними завданнями cron (control-marker-1, control-marker-2 тощо): (crontab -l 2> / dev / null | grep -v control-marker-1; echo '* / 5 * * * * / шлях / до / робота -з аргами # control-marker-1') | crontab -
шеф-кухар

7
Я виявив, що це видаляє існуючі записи на кронтабі, а також мені потрібно було скористатися іншим користувачем (root), тому я використовував наступне для підтримки існуючих записів: echo -e "$(sudo crontab -u root -l)\n* * * * * echo hello > /home/danny/temp.log 2>&1" | sudo crontab -u root -Сподіваємось, це комусь допомагає
Денні

60

Для користувачів crontabs (включаючи root) ви можете зробити щось на кшталт:

crontab -l -u user | cat - filename | crontab -u user -

де файл з назвою "ім'я файлу" містить елементи, які потрібно додати. Ви також можете sedзамість цього зробити маніпуляції текстом, використовуючи інший інструмент cat. Ви повинні використовувати crontabкоманду замість того, щоб безпосередньо змінювати файл.

Аналогічна операція була б:

{ crontab -l -u user; echo 'crontab spec'; } | crontab -u user -

Якщо ви змінюєте або створюєте системні копії, ними можна керувати, як звичайними текстовими файлами. Вони зберігаються в /etc/cron.d, /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthlyкаталогів і файлів /etc/crontabі /etc/anacrontab.


Виглядав перспективним, але спробувавши другий підхід (з echo), я отримав "crontab: error error: ім'я файлу повинно бути вказано для заміни." Сторінка man Cron відображає синтаксис як crontab [ -u user ] file, тобто з обов'язковим ім'ям файлу. Чи є якийсь хитрість, щоб змусити її приймати дані?
Марк Беррі

1
@MarkBerry: Вибачте за це. У трубі слід використовувати дефіс, який вказує, що вхід звідти stdin. Я виправлю свою відповідь.
Призупинено до подальшого повідомлення.

29

В Ubuntu та багатьох інших дистрибутивах ви можете просто помістити файл у /etc/cron.dкаталог, що містить один рядок із дійсним записом crontab . Не потрібно додавати рядок до наявного файлу.

Якщо вам просто потрібно щось запускати щодня, просто вставте файл /etc/cron.daily. Крім того, ви можете також перетягувати файли Into /etc/cron.hourly, /etc/cron.monthlyі /etc/cron.weekly.


5
Але ви повинні мати корінь для цього.
Кіт

17

Ще простішою відповіддю на ваше питання було б:

echo "0 1 * * * /root/test.sh" | tee -a /var/spool/cron/root

Ви можете налаштувати cronjobs на віддалених серверах як нижче:

#!/bin/bash
servers="srv1 srv2 srv3 srv4 srv5"
for i in $servers
  do
  echo "0 1 * * * /root/test.sh" | ssh $i " tee -a /var/spool/cron/root"
done

В Linux місце розташування crontabфайлу за замовчуванням /var/spool/cron/. Тут ви можете знайти crontabфайли всіх користувачів. Вам просто потрібно додати запис cronjob до відповідного файлу користувача. У наведеному вище прикладі до файлу crontab кореневого користувача додається cronjob, який запускається /root/test.shщодня о 1 ранку.


Це було б /var/spool/cron/crontabs/rootна Ubuntu.
Íhor Mé

17

Файли Crontab - це просто текстові файли, і як такі можна розглядати як будь-який інший текстовий файл. Мета crontabкоманди - зробити редагування файлів crontab більш безпечним. Під час редагування за допомогою цієї команди файл перевіряється на наявність помилок і зберігається лише в тому випадку, якщо їх немає.

crontab [path to file]може бути використаний для вказівки хронометражу, що зберігається у файлі. Можливо crontab -e, це встановить файл лише у тому випадку, якщо він не містить помилок.

Тому сценарій може або безпосередньо записати файли вкладки cron, або записати їх у тимчасовий файл і завантажити їх crontab [path to temp file]командою. Запис безпосередньо економить необхідність запису тимчасового файлу, але це також уникає перевірки безпеки.


2
Для ноб, таких як я, зауважте, що це crontab [path to file]. Це, безумовно, був найкращим варіантом для мене, оскільки він дозволяє отримати більш розбірливий код. Я використовую crontab для відстеження посилок і зміни шпалер робочого столу зі статусом. Коли я не чекаю посилок, це не потрібно перевіряти щогодини. Ось чому я хотів, щоб сценарій автоматично редагував частоту кронів.
Расмус

1
@Rasmus Це звучить як дивовижний сценарій, який я хотів би вкрасти. Будь-який шанс поділитися через суть або подібне?
cledoux

8

(У мене недостатньо репутації для коментарів, тому я додаю як відповідь: сміливо додайте це як коментар поруч із його відповіддю)

Один лайнер Джо Касадонте є ідеальним, за винятком випадків, коли ви працюєте з set -e, тобто якщо ваш сценарій встановлений на помилку, і якщо ще немає кронштейнів. У цьому випадку однолінійний НЕ створить cronjob, але НЕ зупинить сценарій. Мовчазний збій може бути дуже оманливим.

Причина полягає в тому, що crontab -lповертається з 1кодом повернення, внаслідок чого наступна команда (the echo) не виконується ... таким чином, cronjob не створюється. Але оскільки вони виконуються як підпроцес (через дужки), вони не зупиняють сценарій.

(Цікаво, що якщо ви знову запустите ту саму команду, вона буде спрацьовувати: коли ви виконали crontab -один раз, crontab -lвсе одно нічого не виводиться, але більше не повертається помилка (повідомлення ви більше не отримуєте no crontab for <user>).echo виконується і crontab створений)

У будь-якому випадку, якщо ви працюєте з set -e, рядок повинен бути:

(crontab -l 2>/dev/null || true; echo "*/5 * * * * /path/to/job -with args") | crontab -

Так, це ще досконаліше.
Yngve Sneen Lindal

7

Як виправлення тих, хто пропонує crontab -l | crontab -: Це працює не в кожній системі. Наприклад, мені довелося додати завдання до кореневого crontab на десятках серверів із запущеною старою версією SUSE (не питайте, чому). Старі SUSE додають рядки коментарів до виходу crontab -l, роблячи crontab -l | crontab -неідентифікаційну (Debian розпізнає цю проблему на сторінці Crontab і виправляє її версію Vixie Cron, щоб змінити поведінку за замовчуваннямcrontab -l ).

Для програмного редагування crontabs в системах, де crontab -lдодаються коментарі, можна спробувати наступне:

EDITOR=cat crontab -e > old_crontab; cat old_crontab new_job | crontab -

EDITOR=catповідомляє crontab використовувати catяк редактор (не звичайний за замовчуванням vi), який не змінює файл, а замість цього копіює його в stdout. Це все ще може бути невдалим, якщо crontab -очікує введення у форматі, відмінному від crontab -eрезультатів. Не намагайтеся замінити фінал crontab -на crontab -e- це не вийде.


4

Ну /etc/crontabпросто файл ascii, тому найпростіший - справедливий

 echo "*/15 * * * *   root     date" >> /etc/crontab

яка додасть роботу, яка надсилатиме вам електронну пошту кожні 15 хвилин. Налаштуйте за смаком і перевіріть за допомогою grepчи іншими способами, чи вже додано рядок, щоб зробити ваш сценарій ідентичним.

На Ubuntu та ін, ви також можете скидати файли, у /etc/cron.*яких простіше зробити і перевірити наявність --- плюс ви не зіпсуєтесь із (системними) конфігураційними файлами, такими як /etc/crontab.


1
Я думаю, що технічно кронд не вимагає моніторингу змін у crontab, навіть якщо насправді це робить більшість реалізацій, тому я рекомендую зателефонувати на crontab -e після цього, щоб подати його. crontab -e вшановує змінну EDITOR, якщо пам'ять служить, тому встановлення її на / bin / true на даний момент повинно просто змусити crontab бути перечитаним.
Ульріх Шварц

1
Правда ще на якийсь - або недавньої системі Linux crond робить монітор, і це , безумовно , робить на заявленої платформі ФПА в.
Дірк Еддельбуеттель

Тільки якщо ви root і хочете, щоб сценарій запускався як root. Це може бути небажаним у випадку з ОП.
Кіт

Не так, у мене є багато некореневих записів у / etc / crontab. Вам просто потрібно судо, щоб додати до файлу. У будь-якому випадку, як я вже заявив, є також /etc/cron.*/, але ви також повинні бути root, щоб писати там.
Дірк Еддельбуеттель

2

Ось як змінити запис у cron, не редагуючи безпосередньо файл cron (який нахмурився).

crontab -l -u <user> | sed 's/find/replace/g' | crontab -u <user> -

Якщо ви хочете видалити запис крона, скористайтеся цим:

crontab -l -u <user> | sed '/find/d' | crontab -u <user> -

Я усвідомлюю, що це не те, про що просив Гаурав, але чому б не знайти всі рішення в одному місці?


1

Я написав інструмент розгортання crontab в python: https://github.com/monklof/deploycron

pip install deploycron

Встановити crontab дуже просто, це об'єднає crontab у існуючий crontab системи.

from deploycron import deploycron
deploycron(content="* * * * * echo hello > /tmp/hello")

1

Це підхід для поступового додавання завдання cron:

  ssh USER_NAME@$PRODUCT_IP nohup "echo '*/2 * * * * ping -c2 PRODUCT_NAME.com >> /var/www/html/test.html' | crontab -u USER_NAME -"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.