it-swarm.com.ru

Как я могу программно создать новую работу cron?

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

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

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

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

109
DavidM

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

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

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

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

109
MarkR

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

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

Добавить что-то в 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 -

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

21
user3865482

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

6
Christian Witts

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

export EDITOR="tee"
echo "0 * * * * /bin/echo 'Hello World'" | crontab -e
5
Renato Tambellini

Предполагая, что в вашем 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

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

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

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

(Sudo crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | Sudo crontab -
2
BuvinJ
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');
1
RafaSashi

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

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

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

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

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

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

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

cat <file> |crontab -
1
Eldamir

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
1
vitaly.v.ch

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

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

Приветствия.

1
Ezra Obiwale

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

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

И вот способ сделать ответ JohnZ и избежать сообщения 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 (например: если расписание изменилось, вы хотите, чтобы оно когда-либо использовалось только один раз). В этом случае нам больше не нужен 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 -
0
rogerdpack

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

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