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

Я хочу иметь возможность программно добавить новое задание, что является лучшим способом сделать это?

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

(crontab -l ; echo "0 * * * * wget -O - -q http://www.example.com/cron.php") | crontab -

есть ли лучший способ?

16 ответов


это всегда хорошо работало для меня.

вы должны рассмотреть немного более сложный скрипт, который может делать три вещи.

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

  2. удалите строку crontab. Возможно, только предупреждение, если его не существует.

  3. комбинация вышеуказанных двух функций для замены строки crontab.


лучший способ, если вы работаете как root, - это поместить файл в /etc / cron.d

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

имя файла: /etc/cron.d/per_minute

содержание: * * * * * root /bin/sh /home/root/script.sh


решение OP имеет ошибку, оно может позволить добавлять записи дважды, используйте ниже для исправления.

(crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | crontab -

чтобы добавить что-то в cron

(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | sort | uniq | crontab -

чтобы удалить это из cron

(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | grep -v hupChannel.sh |  sort | uniq | crontab -

надежда поможет кому-то


Если вы планируете сделать это для сценария запуска один раз для просто wget'ING что-то, взгляните на 'at'


просто измените редактор на команду tee:

"экспорт" редактор="тройник"

Эхо "0 * * * * /bin / echo 'Hello World' " / crontab-e


предполагая, что в вашем crontab уже есть запись, следующая команда должна работать относительно хорошо. Обратите внимание, что $CMD переменная только для чтения. Сортировка перед фильтрацией дубликатов важна, потому что uniq работает только на соседних линиях.

CMD='wget -O - -q http://www.example.com/cron.php"'
(crontab -l ; echo "0 * * * * $CMD") | sort | uniq | crontab -

если у вас в настоящее время есть пустой crontab, вы получите следующую ошибку в stderr:

no crontab for user

если вы хотите избежать этого, вы можете добавить немного сложности добавить do что-то вроде этого:--6-->

(crontab -l ; echo "0 * * * * $CMD") 2>&1 | sed "s/no crontab for $(whoami)//"  | sort | uniq | crontab -

добавление к ответу JohnZ, вот синтаксис для планирования как root, если вы sudoer:

(sudo crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | sudo crontab -

man crontab также полезен:

CRONTAB (1)

имя

   crontab - manipulate per-user crontabs (Dillon's Cron)

справка

   crontab file [-u user] - replace crontab from file

   crontab - [-u user] - replace crontab from stdin

   crontab -l [user] - list crontab for user

function cronjob_exists($command){

    $cronjob_exists=false;

    exec('crontab -l', $crontab);


    if(isset($crontab)&&is_array($crontab)){

        $crontab = array_flip($crontab);

        if(isset($crontab[$command])){

            $cronjob_exists=true;

        }

    }
    return $cronjob_exists;
}

function append_cronjob($command){

    if(is_string($command)&&!empty($command)&&cronjob_exists($command)===FALSE){

        //add job to crontab
        exec('echo -e "`crontab -l`\n'.$command.'" | crontab -', $output);


    }

    return $output;
}

    append_cronjob('* * * * * curl -s http://localhost/cron/test.php');

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

crontab -l 2>/dev/null | grep -q '/path/to/script' || echo "5 * * * * /path/to/script" | crontab -

Ура.


трубопровод stdout в crontab не устанавливал новый crontab для меня на macOS, поэтому я нашел это решение вместо этого, используя tee редактор в sub shell:

(EDITOR=tee && (crontab -l ; echo "@daily ~/my-script.sh" ) | uniq - | crontab -e)

вот еще один однострочный способ, который позволяет избежать дублирования

(crontab -l 2>/dev/null | fgrep -v "*/1 *  *  *  * your_command"; echo "*/1 *  *  *  * your_command") | crontab -

и вот способ сделать ответ Джонса и избежать no crontab for user сообщение, или если вам нужно работать в set -eu введите среду и ничего не может вернуть сбой (в этом случае 2>/dev/null часть не является обязательным):

( (crontab -l 2>/dev/null || echo "")  ; echo "0 * * * * your_command") | sort -u - | crontab -

или если вы хотите разделить вещи так, чтобы они были более читаемыми:

new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
(echo "$preceding_cron_jobs" ; echo "$new_job") | sort - | uniq - | crontab -

или дополнительно удалить любые ссылки на your_command (например: если расписание имеет изменен, вы только хотите, чтобы он когда-либо cron'Ed один раз). В этом случае нам больше не нужно uniq (добавлен бонус, порядок вставки также сохраняется):

new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
preceding_cron_jobs=$(echo "$preceding_cron_jobs" | grep -v your_command )
(echo "$preceding_cron_jobs" ; echo "$new_job") | crontab -

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

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

чтобы полностью переписать crontab, сделайте

echo "2 2 2 2 2 /bin/echo foobar" |crontab -

Это должно быть легко объединить с другими ответами, описанными здесь, как

crontab -l | <something> | tee |crontab -

или, если у вас есть содержимое в файле, это еще проще

cat <file> |crontab -

также вы можете добавить свои задачи в /etc/cron-а.*/


вы также можете редактировать текстовый файл таблицы cron напрямую, но ваше решение кажется вполне приемлемым.