Cron (Русский) - ArchWiki

# Cron (Русский)

From ArchWiki
Jump to navigation Jump to search

Эта страница нуждается в сопроводителе

Статья не гарантирует актуальность информации. Помогите русскоязычному сообществу поддержкой подобных страниц. См. Команда переводчиков ArchWiki

Related articles

- Systemd/Tаймеры

Из Википедии:

cron - классический демон-планировщик задач в UNIX-подобных операционных системах, использующийся для периодического выполнения заданий в определённое время. Регулярные действия описываются инструкциями, помещенными в файлы crontab и в специальные директории.

## Установка

Существует множество реализаций cron, но ни одна из них не устанавливается по умолчанию, т.к. система использует вместо него systemd/Timers. См. руководство по cron для Gentoo, в котором представлены сравнения.

Доступные пакеты:

- cronie
- fcron
- bcronAUR[ссылка недействительна: сохранено в aur-mirror]
- dcronAUR
- vixie-cronAUR
- scron-gitAUR

## Настройка

### Активация и автозапуск

После установки демон не будет включен по умолчанию. Установленный пакет устанавливает службу, которая может контролироваться systemctl. Например, для cronie это `cronie.service`.

Текущие активные задания расположены в папках вроде `/etc/cron.daily/` и запуск службы cron активирует их все.

Note: cronie предоставляет ежечасную задачу `0anacron` , которая осуществляют отложенный запуск других задач, например, если компьютер был выключен во время срабатывания задачи по расписанию.

### Обработка ошибок в заданиях

cron регистрирует стандартный вывод из stdout и stderr и пытается отправить его на электронную почту пользователя используя команду `sendmail`. В cronie такие сообщения на электронную почту отключены, если отсутствует файл `/usr/bin/sendmail`. Для того, чтобы электронные письма направлялись пользователю, в системе должен быть запущен smtp-демон, например opensmtpd. Также вы можете установить пакет, который предоставляет команду sendmail и настроить его на отсылку почту удаленному адресату. Ну и наконец, вы можете вести лог при помощи команды `-m` и скрипта.

#### Пример с msmtp

This article or section needs expansion.

Reason: How exactly do I make sure it detects the new `sendmail` command? (Discuss in Talk:Cron (Русский)#)

Установите пакет msmtp-mta, который создаст символическую ссылку с `/usr/bin/sendmail` на `/usr/bin/msmtp`. Перезапустите `cronie`, чтобы убедиться, что служба обнаружила новую команду `sendmail`. Теперь вам нужно как-то конвертировать для `msmtp` ваше имя пользователя в адрес электронной почты.

Затем либо добавьте строку `MAILTO` в файл crontab, например, так:

    MAILTO=your@email.com

либо создайте файл `/etc/msmtprc` и напишите в него строку:

    aliases /etc/aliases

Создайте файл `/etc/aliases`:

    your_username: your@email.com
    # Optional:
    default: your@email.com

Затем измените конфигурацию демона cronie заменив команду `ExecStart` на:

    ExecStart=/usr/bin/crond -n -m '/usr/bin/msmtp -t'

#### Пример с esmtp

Установите esmtp и procmail.

После установки настройте транспорт почты:

    /etc/esmtprc

    identity myself@myisp.com
           hostname mail.myisp.com:25
           username "myself"
           password "secret"
           starttls enabled
           default
    mda "/usr/bin/procmail -d %T"

Для работы в режиме доставки Procmail требует права суперпользователя, но это не проблема, т.к. вы все равно запускаете задания cron от имени root.

Чтобы проверить, что все работает, создайте файл `message.txt` с `"test message"` внутри.

Из той же папки запустите:

    $ sendmail user_name < message.txt

Затем:

    $ cat /var/spool/mail/user_name

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

Поток ошибок всех активных заданий теперь перенаправлен в `/var/spool/mail/user_name`.

В связи с ограничениями прав, довольно непросто создавать и отправлять электронные письма пользователю root (например, так: `su -c ""`). В `esmtp` можно настроить пересылку сообщений, адресованных root, обычному пользователю:

    /etc/esmtprc

    force_mda="user-name"

Note: Если вышенаписанное не сработает, можете попробовать создать локальную копию `~/.esmtprc` с тем же содержанием.

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

    $ chmod 710 ~/.esmtprc

Затем повторите тест с отправкой `message.txt` точно так же, как описано выше.

#### Пример с opensmtpd

Установите opensmtpd.

Отредактируйте `/etc/smtpd/smtpd.conf`. Следующая конфигурация подходит для локальной доставки почты:

    listen on localhost
    accept for local deliver to mbox

Можете начинать тестировать ее. Для начала запустите `smtpd.service`. Затем:

    $ echo test | sendmail user

user может проверить свою почту любым клиентом, способным распознать формат mbox, либо просто посмотреть файл `/var/spool/mail/user`. Если все прошло нормально, можете включить opensmtpd.

Этот метод имеет то преимущество, что не нужно отправлять уведомления cron на удаленный сервер, не нужно даже никакого сетевого соединения. С другой стороны, в памяти системы висит еще один демон.

Note:

- На момент написания статьи пакет opensmtpd не создает все необходимые папки в `/var/spool/smtpd`, но демон предупредит об этом, указав все необходимые права и владельцев. Просто создайте нужные папки самостоятельно.
- Даже несмотря на то, что предложенная конфигурация не принимает удаленные подключения, хорошей практикой является добавить дополнительный слой безопасности, заблокировав порт 25 в iptables или другом файерволле.

#### Длительные задания cron

Представьте, что в cron загружена следующая программа:

    #!/bin/sh
    echo "I had a recoverable error!"
    sleep 1h

Что произойдет?

1. cron запускает скрипт
2. как только cron видит какой-то вывод, он запускает вашу почтовую систему и создает некоторые заголовки. Он оставляет поток открытым, потому что задание не завершено и может быть больше выходных данных.
3. почтовая система открывает соединение с postfix и оставляет его открытым, пока ждет окончания тела письма.
4. postfix закрывает простаивающее соединение раньше, чем проходит один час, и вы получаете ошибку вроде этой:

    smtpmsg='421 … Error: timeout exceeded' errormsg='the server did not accept the mail'

Для того, чтобы решить эту проблему, вам понадобятся команды chronic или sponge из пакета moreutils.

С их man-страниц:

chronic
  chronic запускает команду и организовывает ее стандартные потоки вывода и ошибок так, что отображается только неправильный результат работы программы (выход с ненулевым значением или сбой). Если команда выполнена успешно, любые дополнительные выходные данные будут скрыты.
sponge
  sponge получает стандартный входной поток и пишет его в специальный файл. В отличие от перенаправления командной строки, sponge аггрегирует весь свой входной поток в выходной файл. Если выходной файл не указан, sponge выводит данные в stdout.

Даже если это не указано явно, chronic буферизирует выходные данные команды перед тем, как открыть stdout (как и sponge)

## Формат crontab

Основной формат для crontab таков:

    минута час день_месяца месяц день_недели команда

- минута - значение от 0 до 59
- час - значение от 0 до 23
- день_месяца - значение от 1 до 31
- месяц - значение от 1 до 12
- день_недели - значение от 0 до 6, где 0 - это воскресенье.

Несколько вызовов могут быть перечислены через запятую, интервал может быть задан через дефис, а звёздочка означает любой символ. Пробелы используются для разделения полей. К примеру, строка

    */5 9-16 * 1-5,9-12 1-5 ~/bin/i_love_cron.sh

вызовет скрипт `i_love_cron.sh` каждые пять минут с 9 AM до 4:55 PM по будням (уточнить, неделя может начинаться с воскресенья) кроме летних месяцев (июнь, июль, август). Больше примеров и дополнительные настройки могут быть найдены ниже.

## Базовые команды

Crontabs никогда не редактируются напрямую; вместо этого пользователи должны использовать `crontab` утилиту для работы со своими crontabs. Чтобы получить доступ к этой утилите, пользователь должен быть членом группы `users` (смотри команду `gpasswd`).

Чтобы просмотреть свои crontabs, пользователь может воспользоваться коммандой:

    $ crontab -l

Для редактирования своих crontabs:

    $ crontab -e

Note: По умолчанию команда `crontab` использует редактор `vi`. Чтобы изменить это, экспортируйте `EDITOR` или `VISUAL`, или укажите редактор напрямую: `EDITOR=vim crontab -e`.

Чтобы удалить свои crontabs:

    $ crontab -r

Если пользователь имеет сохранённые crontab и хочет полностью перезаписать свои старые crontab, он может воспользоваться:

    $ crontab saved_crontab_filename

Чтобы перезаписать crontab из командной строки (Wikipedia:stdin), используйте

    $ crontab -

Чтобы отредактировать чьи-либо ещё crontab, вызовите следующую команду из под root:

    # crontab -u username -e

Этот же формат (присоединяя `-u username` к команде) работает так же для чтения и удаления crontabs.

## Примеры

Запись:

    01 * * * * /bin/echo Hello, world!

выполняет команду `/bin/echo Hello, world!` в первую минуту каждого часа каждого дня (т.е. в 12:01, 1:01, 2:01, etc.).

Аналогично:

    */5 * * jan mon-fri /bin/echo Hello, world!

выполняет то же действие каждые пять минут по будним дням в течение Января (т.е. в 12:00, 12:05, 12:10, etc.).

Строка (как указано в "man 5 crontab"):

    *0,*5 9-16 * 1-5,9-12 1-5 /home/user/bin/i_love_cron.sh

вызывает скрипт `i_love_cron.sh` в пятиминутные интервалы с 9 AM до 5 PM (не включая 5 PM) каждый будний день каждого месяца, кроме летних.

Periodical settings can also be entered as in this crontab template:

    # Chronological table of program loadings
    # Edit with "crontab" for proper functionality, "man 5 crontab" for formatting
    # User: johndoe

    # mm  hh  DD  MM  W /path/progam [--option]...  ( W = weekday: 0-6 [Sun=0] )
      21  01  *   *   * /usr/bin/systemctl hibernate
      @weekly           $HOME/.local/bin/trash-empty

## Default editor

To use an alternate default editor, define the `EDITOR` environment variable in a shell initialization script as described in Environment variables.

As a regular user, `su` will need to be used instead of `sudo` for the environment variable to be pulled correctly:

    $ su -c "crontab -e"

To have an alias to this `printf` is required to carry the arbitrary string because `su` launches in a new shell:

    alias scron="su -c $(printf "%q " "crontab -e")"

## run-parts issue

cronie uses `run-parts` to carry out script in `cron.daily`/`cron.weekly`/`cron.monthly`. Be careful that the script name in these won't include a dot (.), e.g. `backup.sh`, since `run-parts` without options will ignore them (see: run-parts(8)).

## Running X.org server-based applications

Cron does not run under the X.org server therefore it cannot know the environmental variable necessary to be able to start an X.org server application so they will have to be defined. One can use a program like xuserrunAUR[ссылка недействительна: сохранено в aur-mirror] to do it:

    17 02 * ... /usr/bin/xuserrun /usr/bin/xclock

Or then can be defined manually (`echo $DISPLAY` will give the current DISPLAY value):

    17 02 * ... env DISPLAY=:0 /usr/bin/xclock

If done through say SSH, permission will need be given:

    # xhost +si:localuser:$(whoami)

## Asynchronous job processing

If you regularly turn off your computer but do not want to miss jobs, there are some solutions available (easiest to hardest):

### Cronie

cronie comes with anacron included. The project homepage reads:

Cronie contains the standard UNIX daemon crond that runs specified programs at scheduled times and related tools. It is based on the original cron and has security and configuration enhancements like the ability to use pam and SELinux.

### Dcron

Vanilla dcronAUR supports asynchronous job processing. Just put it with @hourly, @daily, @weekly or @monthly with a jobname, like this:

    @hourly         ID=greatest_ever_job      echo This job is very useful.

### Cronwhip

cronwhipAUR is a script to automatically run missed cron jobs; it works with the former default cron implementation, dcron. See also the forum thread.

### Anacron

Anacron is a full replacement for dcron which processes jobs asynchronously.

It is provided by cronie. The configuration file is `/etc/anacrontab`. Information on the format can be found in the `anacrontab(5)` man page. Running `anacron -T` will test `/etc/anacrontab` for validity.

### Fcron

Like anacron, fcron assumes the computer is not always running and, unlike anacron, it can schedule events at intervals shorter than a single day which may be useful for systems which suspend/hibernate regularly (such as a laptop). Like cronwhip, fcron can run jobs that should have been run during the computer's downtime.

When replacing cronie with fcron be aware the spool directory is `/var/spool/fcron` and the `fcrontab` command is used instead of crontab to edit the user crontabs. These crontabs are stored in a binary format with the text version next to them as foo.orig in the spool directory. Any scripts which manually edit user crontabs may need to be adjusted due to this difference in behavior.

A quick scriptlet which may aide in converting traditional user crontabs to fcron format:

    cd /var/spool/cron && (
     for ctab in *; do
      fcrontab ${ctab} -u ${ctab}
     done
    )

See also the forum thread.

## Ensuring exclusivity

If you run potentially long-running jobs (e.g., a backup might all of a sudden run for a long time, because of many changes or a particular slow network connection), then `flock` (util-linux) can ensure that the cron job won't start a second time.

      5,35 * * * * /usr/bin/flock -n /tmp/lock.backup /root/make-backup.sh

## cronie

Long time users of vixie-cron (traditional cron) will be confused by how cronie is set up. Here is the relevant file hierarchy:

       /etc
         |----- anacrontab
         |----- cron.d
                  | ----- 0hourly
         |----- cron.daily
         |----- cron.deny
         |----- cron.hourly
         |----- cron.monthly
         |----- cron.weekly
         |----- crontab

Note that the crontab file is not created by default, but jobs added here will be run if you wish to use this file. Cronie provides both cron and anacron functionality. The difference is that cron will run jobs at particular time intervals (down to a granularity of one minute) if the machine is on at the particular time specified, while anacron runs jobs (with a minimum daily granularity) without assuming that the machine is turned on all the time. When the machine is on, anacron will check to see if there are any jobs that should have been run and will run them accordingly. The `/etc/cron.d` and `/etc/cron.hourly` directories are associated with cron functionality, while the `/etc/anacrontab` file and `/etc/cron.daily`, `/etc/cron.weekly`, and `/etc/cron.monthly` directories are associated with anacron functionality. The `/etc/cron.deny` file is there so that any user who is not specifically prohibited can create their own cron jobs.

To implement a system-wide cron job, create a crontab-like file for it and place it in the `/etc/cron.d` directory or add the job to /etc/crontab. Any executable (these are almost always shell scripts) in `/etc/cron.hourly` will be run every hour.

Anacron functionality is implemented similarly, however using the `/etc/cron.daily`, `/etc/cron.weekly`, or `/etc/cron.monthly` directories, depending on how frequently you want the job to be run. The anacron job files are also executables; i.e. not in crontab-format. Anacron is triggered at the beginning of every hour by the crontab file `/etc/cron.d/0hourly` which runs the executables in `/etc/cron.hourly` including the file `/etc/cron.hourly/0anacron` - deleting these will prevent anacron running any daily, weekly or monthly tasks.

Note: the output of `systemctl status cronie` might show a message such as `crond[<PID>]: (root) CAN'T OPEN (/etc/crontab): No such file or directory`. However, this is not an error as of cronie 1.4.8. See this discussion.

## Dcron

The cron daemon parses a configuration file known as `crontab`. Each user on the system can maintain a separate crontab file to schedule commands individually. The root user's crontab is used to schedule system-wide tasks (though users may opt to use `/etc/crontab` or the `/etc/cron.d` directory, depending on which cron implementation they choose).

    /var/spool/cron/root

    # Run command at a scheduled time
    # Edit this 'crontab -e' for error checking, man 1 crontab for acceptable format

    # <@freq>                       <tags and command>
    @hourly         ID=sys-hourly   /usr/sbin/run-cron /etc/cron.hourly
    @daily          ID=sys-daily    /usr/sbin/run-cron /etc/cron.daily
    @weekly         ID=sys-weekly   /usr/sbin/run-cron /etc/cron.weekly
    @monthly        ID=sys-monthly  /usr/sbin/run-cron /etc/cron.monthly

    # mm  hh  DD  MM  W /path/command (or tags) # W = week: 0-6, Sun=0
      21  01  *   *   * /usr/bin/systemctl suspend

These lines exemplify one of the formats that crontab entries can have, namely whitespace-separated fields specifying:

1. @period
2. ID=jobname (this tag is specific to dcron)
3. command

The other standard format for crontab entries is:

1. minute
2. hour
3. day
4. month
5. day of week
6. command

The crontab files themselves are usually stored as `/var/spool/cron/username`. For example, root's crontab is found at `/var/spool/cron/root`

See the crontab man page for further information and configuration examples.

## See also

- Gentoo Linux Cron Guide

Categories:

- Daemons (Русский)
- Русский

Hidden categories:

- Pages with broken package links
- Pages or sections flagged with Template:Expansion