cron (日本語)

From ArchWiki
Revision as of 12:34, 31 December 2013 by Kusakata (Talk | contribs)

Jump to: navigation, search

Template:Related articles start (日本語)

  • systemd/cron functionality
  • </ul></div>

    Wikipedia より:

    cron は Unix ライクなコンピュータオペレーティングシステムにおける時間基準のジョブスケジューラです。cron を使うことでジョブ (コマンドやシェルスクリプト) をスケジュールして定期的に特定の時刻・時間に実行することが可能になります。システムのメンテナンスや管理を自動化するためによく使われます。

    インストール

    croniebase グループの一部としてデフォルトでインストールされます。他の cron 実装も存在します、Gentoo の cron ガイド に比較があります。例えば fcron, bcronAUR, vixie-cronAUR など。2011年5月までは Arch Linux のデフォルトの cron 実装は dcronAUR でした。

    設定

    ユーザーと自動起動

    新しいシステムにログインした時に root スクリプトを動かすために cron は動作しているはずです。このことは /var/log/ にあるログを見ることで確認できます。crontab アプリケーション (ジョブエントリのエディタ) を使うには、ユーザーは指定されているグループ usersroot のどちらかのメンバーである必要があります。全てのユーザーは既にメンバーになっているはずです。cron をブート時に起動させるには、systemctl を使って cronie.servicedcron.service など使用している cron の実装のサービスを有効にしてください。

    ジョブのエラーの対処

    cron は stdoutstderr からの出力を記録して sendmail コマンドを使ってユーザーのスプールにメールで送信しようと試みます。/usr/bin/sendmail が存在しない場合 Cronie はメール出力を無効化します。これらのメッセージをログとして記録するには -m オプションを使ってスクリプトを書くか基本的な SMTP サブシステムをインストールしてください。

    1. cronie.service ユニットを編集する。
    2. esmtp, msmtp, opensmtpd をインストールする、もしくはカスタムスクリプトを書く。

    msmtp の例

    Here are two ways to obtain emails from cronie with msmtp:

    1. Install the msmtp-mta package which effectively creates a symbolic link from /usr/bin/sendmail to /usr/bin/msmtp. You must then provide a way for msmtp to convert your username into an email address.
      • Either add a MAILTO line to your crontab, like so:
        MAILTO=your@email.com
        or:
      • Add this line to /etc/msmtprc:
        aliases /etc/aliases
        and create /etc/aliases:
        your_username: your@email.com
        # Optional:
        default: your@email.com
    2. Edit the cronie.service unit. For example, create /etc/systemd/system/cronie.service.d/msmtp.conf:
      [Service]
      ExecStart=
      ExecStart=/usr/bin/crond -n -m '/usr/bin/msmtp -t'
    Note: The empty ExecStart= cancels any previous ExecStart commands.

    esmtp の例

    Install esmtp and procmail.

    After installation configure the routing:

    /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 needs root privileges to work in delivery mode but it is not an issue if you are running the cronjobs as root anyway.

    To test that everything works correctly, create a file message.txt with "test message" in it.

    From the same directory run:

    $ sendmail user_name < message.txt 
    

    then:

    $ cat /var/spool/mail/user_name
    

    You should now see the test message and the time and date it was sent.

    The error output of all jobs will now be redirected to /var/spool/mail/user_name.

    Due to the privileged issue, it is hard to create and send emails to root (e.g. su -c ""). You can ask esmtp to forward all root's email to an ordinary user with:

    /etc/esmtprc
    force_mda="user-name"
    Note: If the above test didn't work, you may try creating a local configuration in ~/.esmtprc with the same content.

    Run the following command to make sure it has the correct permission:

    $ chmod 710 ~/.esmtprc
    
    Then repeat the test with message.txt exactly as before.

    opensmtpd の例

    Install opensmtpd.

    Edit /etc/smtpd/smtpd.conf. The following configuration allows for local delivery:

    listen on localhost
    accept for local deliver to mbox
    

    You can proceed to test it:

    # systemctl start smtpd
    $ echo test | sendmail user
    

    user can check his/her mail in with any reader able to handle mbox format, or just have a look at the file /var/spool/mail/user. If everything goes as expected, you can enable opensmtpd for future boots:

    # systemctl enable smtpd
    

    This approach has the advantage of not sending local cron notifications to a remote server. Not even network connection is needed. On the downside, you need a new daemon running.

    Note:
    • At the moment of writing the Arch opensmtpd package does not create all needed directories under /var/spool/smtpd, but the daemon will warn about that specifying the required ownerships and permissions. Just create them as suggested.
    • Even though the suggested configuration does not accept remote connections, it's a healthy precaution to add an additional layer of security blocking port 25 with iptables or similar.

    長い cron ジョブ

    Suppose this program is invoked by cron :

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

    What happens is this:

    1. cron runs the script
    2. as soon as cron sees some output, it runs your MTA, and provides it with the headers. It leaves the pipe open, because the job hasn't finished and there might be more output.
    3. the MTA opens the connection to postfix and leaves that connection open while it waits for the rest of the body.
    4. postfix closes the idle connection after less than an hour and you get an error like this :
    smtpmsg='421 … Error: timeout exceeded' errormsg='the server did not accept the mail'
    

    To solve this problem you can use the command chronic or sponge from moreutils. From their respective man page:

    chronic
    chronic runs a command, and arranges for its standard out and standard error to only be displayed if the command fails (exits nonzero or crashes). If the command succeeds, any extraneous output will be hidden.
    sponge
    sponge reads standard input and writes it out to the specified file. Unlike a shell redirect, sponge soaks up all its input before opening the output file… If no output file is specified, sponge outputs to stdout.

    Even if it's not said chronic buffer the command output before opening its standard output (like sponge does).

    Crontab のフォーマット

    crontab の基本的なフォーマットは:

    minute hour day_of_month month day_of_week command
    
    • minute は 0 から 59 までの値。
    • hour は 0 から 23 までの値。
    • day_of_month は 1 から 31 までの値。
    • month は 1 から 12 までの値。
    • day_of_week は 0 から 6 までの値、0 が日曜日。

    カンマを使うことで複数の時間を指定することが出来ます。時間の範囲はハイフンで決めることができ、アスタリスクはワイルドカード文字になります。スペースはフィールドを分けるのに使います。例えば、次の行はスクリプト i_love_cron.sh を夏の期間 (6月, 7月, 8月) を除く平日の午前9時から午後4:55まで5分間隔で実行します:

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

    他の例や高度な設定テクニックは下を見て下さい。

    基本的なコマンド

    Crontab を直接編集してはいけません。代わりに、ユーザーは crontab プログラムを使って crontab を編集してください。このコマンドを実行するには、ユーザーは users グループのメンバーである必要があります (gpasswd コマンドを見て下さい)。

    crontab を一覧するには、次のコマンドを実行してください:

    $ crontab -l
    

    crontab を編集するには、次のコマンドを使って下さい:

    $ crontab -e
    

    crontab を削除するには、次のコマンドを使って下さい:

    $ crontab -r
    

    既に crontab が存在していて、古い crontab を完全に上書きするには次を使って下さい:

    $ crontab saved_crontab_filename
    

    コマンドライン (Wikipedia:ja:標準ストリーム) から crontab を上書きするには:

    $ crontab - 
    

    他の誰かの crontab を編集するには、次のコマンドを root で実行してください:

    # crontab -u username -e
    

    This same format (appending -u username to a command) works for listing and deleting crontabs as well.

    サンプル

    コマンド /bin/echo Hello, world! を毎月の毎日の毎時間の1分目 (つまり 12:01, 1:01, 2:01 ...) に実行するエントリ:

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

    1月の平日に5分ごと (つまり 12:00, 12:05, 12:10 ...) に同じジョブを実行するエントリ:

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

    次の行は夏 (6月, 7月, 8月) 以外の毎月の平日 (月-金) の午前9時から午後5時まで5分間隔で (午後5時0分は除く) スクリプト i_love_cron.sh を実行します ("man 5 crontab" より):

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

    定期的な設定は次の crontab テンプレートのように入力することも可能です:

    # 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
    

    デフォルトエディタ

    To use an alternate default editor, define the EDITOR environment variablee it in a shell initialization script (vim-default-editorAUR is available for vim users). For example:

    /etc/profile.d/nano-default-editor
    #!/bin/sh
    
    export EDITOR=/usr/bin/nano
    

    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: man run-parts).

    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 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.

    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

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

    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. Like cronwhip, it can run jobs that should have been run during the computer's downtime. 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 lockrunAUR can ensure that the cron job won't start a second time.

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

    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.

    参照