プログラムで新しいcronジョブを作成するにはどうすればよいですか?


129

プログラムで新しいcronジョブを追加できるようにしたいのですが、これを行う最善の方法は何ですか?

私の研究から現在のcrontabをダンプしてから新しいcrontabを追加し、それをcrontabにパイプで戻すことができるようです:

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

もっと良い方法はありますか?


2
あなたの解決策は良いもののようです。
クレイグS

Solarisでは、最後のcrontabのダッシュを削除するだけです。そこにすでに行が追加されないようにgrepを追加できます。
lacroix1547


括弧の代わりに中括弧は、プロセスを生成せずにそれを行います。中かっこの周りにスペースを入れてください、{...; }。
ジェイウィンストン

回答:


-25

それはいつも私にとってうまくいきます。

3つのことを実行できる、もう少し高度なスクリプトを検討する必要があります。

  1. crontab行を追加します。それが存在しないことを保証します。既に存在する場合に追加するのは悪いです。

  2. crontab行を削除します。おそらく、存在しない場合にのみ警告します。

  3. crontab行を置き換える上記の2つの機能の組み合わせ。


78
彼はどのように尋ね、あなたは彼に何を伝えますか?
セリン、2011年

1
ユーザーがまだcrontabを持っていない場合はどうなりますか?
Maxim Egorushkin 2016年

132

ルートとして実行している場合の最善の方法は、ファイルを/etc/cron.dにドロップすることです。

パッケージマネージャーを使用してソフトウェアをパッケージ化する場合、そのディレクトリにファイルを置くだけで、それらはcrontabであるかのように解釈されますが、ユーザー名の追加フィールドがあります。例:

ファイル名: /etc/cron.d/per_minute

コンテンツ: * * * * * root /bin/sh /home/root/script.sh


5
使用しているcronのバージョンが/etc/cron.d/をサポートしていることを確認してください。最近のほとんどのLinuxディストリビューションがサポートしています。
sleske 2009年

8
これは、最もシンプルで最もエレガントなソリューションです。もちろん、既存のcrontabを他の関連しないエントリで解析して編集する必要はありません。
セリン、2011年

13
これに対する潜在的な注意点の1つは、cronがこのフォルダへの新しい追加を取得する頻度です(1時間に1回)。あなたの仕事がすぐに走り始めることを期待しているなら、用心してください。
JonathanK

6
@ JonathanK、cronに再スキャンを要求できるかどうかを知っていますか/etc/cron.d/*?確認のために1時間待つ必要がある場合、何かが機能しているかどうかを知るのは困難です。
2014

4
このファイルにpermsを設定するにはどうすればよいですか?chmod + x /etc/cron.d/per_minute?
GIO

101

OPのソリューションにはバグがあり、エントリを2回追加できる場合があります。以下を使用して修正してください。

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

5
これは、説明されていないにしても、実際には優れたソリューションです。コマンドがcrontabに2回追加されないようにします。
Bufke 2013

2
これは、重複エントリの問題を修正するのに適しています。その間にcrontabに別の行が追加された場合はどうなりますか?
hmn 2013

6
ただ、一意性を確保するためにsort前にuniq:、例えば(crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | crontab -
mway

6
必要はありませんuniq。の-uオプションを使用しますsort
papiro 16

6
最初にcrontabを編集するときに、ユーザーのcrontabが表示されないようにする方法。
wyx 2017

23

何かを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 -

誰かを助けることを願っています


これはまさに私が探していたもので、これを追加するだけです。grep -v '^#' | コメントを
除外する

2
2>&1 | grep -v "no crontab"crontabがない場合、出力行crontab: no crontab for...はstderrに送信されるため、実際には必要ありません。その出力をキャプチャしてstdoutに送信し、grepを使用してフィルタリングする理由はありません。crontab: no crontab for...出力に表示されないようにすることが目的の場合は、を使用します2> /dev/null | sort....
マティ


6

エディターをteeコマンドに変更するだけです。

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

3
注意-これは既存のエントリをすべて消去します。
starfry

5

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 -

5

ここでのソリューションのほとんどは、crontabに行を追加するためのものです。さらに制御が必要な場合は、crontabの内容全体を制御できるようにする必要があります。

パイピングを使用して、これをかなりエレガントに行うことができます。

crontabを完全に書き換えるには、

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

これは、ここで説明されている他の回答と簡単に組み合わせることができます

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

または、ファイルにコンテンツがある場合は、さらに簡単です

cat <file> |crontab -

3

これは、重複を回避する別のワンライナー方法です

(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への参照をすべて削除します(例:スケジュールが変更された場合、一度だけcron化する必要があります)。この場合、もう必要ありません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 -

2

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

3
「crontabをstdinから置き換える」という部分は実際には答えの半分です:-)
グロドリゲス14

2

JohnZの回答に加えて、sudoerの場合にrootとしてスケジュールする構文は次のとおりです。

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

1
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

これにより、コマンドを追加する前に、コマンドが存在しないことを確認します。

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

乾杯。


0

stdoutをcrontabpipingしてmacOSに新しいcrontabをインストールしなかったので、サブシェルでteeエディターを使用して、このソリューションを代わりに見つけました:

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

0

タスクをユーザーとして実行する場合:

crontab -l | { cat; echo "@weekly what_you_want_to_execute"; } | crontab -

タスクを特権で実行する場合:

sudo crontab -l | { cat; echo "@weekly what_you_want_to_execute"; } | sudo crontab -

そして、タスクをチェックします( 'sudo'の有無にかかわらず):

crontab -l | sed '/^$/d; /#/d'


-2

cronテーブルのテキストファイルを直接編集することもできますが、ソリューションは完全に許容できるようです。


1
同時編集がファイルの破損を引き起こす可能性を懸念しているので、私はこれを恐れます。コマンドラインのcrontabコマンドを使用すると、この問題を回避できます。
Craig S

クレイグ、これ以上の調査がなければ、コマンドラインバージョンがアトミックで競合条件に対して安全であるかどうか確信が持てません。とにかく「かなり安全」でしょう。
tuomassalo 2011年

「ファイルの直接編集」はrootアクセスなしでは実行できません(ユーザーのcrontabファイルがどこにあるか、およびcronデーモンが変更を正しく受信するようにする方法を理解できる場合)。プログラムでの「編集」は問題のようですそもそもアドバイスが欲しい。
トリプルリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.