プログラムで新しいcronジョブを追加できるようにしたいのですが、これを行う最良の方法は何ですか?
私の研究 から、現在のcrontabをダンプしてから、新しいcrontabを追加して、それをcrontabに戻すことができるようです:
(crontab -l ; echo "0 * * * * wget -O - -q http://www.example.com/cron.php") | crontab -
もっと良い方法はありますか?
ルートとして実行している場合の最良の方法は、ファイルを/etc/cron.dにドロップすることです
パッケージマネージャーを使用してソフトウェアをパッケージ化する場合、そのディレクトリにファイルを置くだけで、それらはcrontabであると解釈されますが、ユーザー名用の追加フィールドがあります:
ファイル名: /etc/cron.d/per_minute
コンテンツ:* * * * * root /bin/sh /home/root/script.sh
OPのソリューションにはバグがあり、エントリを2回追加できる場合があります。以下を使用して修正します。
(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 'するための1回限りのシナリオでそれを行うことを計画している場合は、 ' at ' を見てください。
エディターをteeコマンドに変更するだけです:
export EDITOR="tee"
echo "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
これを避けたい場合は、少し複雑さを追加して、次のように追加します。
(crontab -l ; echo "0 * * * * $CMD") 2>&1 | sed "s/no crontab for $(whoami)//" | sort | uniq | crontab -
ここでの解決策のほとんどは、crontabに行を追加するためのものです。さらに制御が必要な場合は、crontabの内容全体を制御できるようにする必要があります。
パイピングを使用して、これを非常にエレガントに行うことができます。
Crontabを完全に書き換えるには、次のようにします。
echo "2 2 2 2 2 /bin/echo foobar" |crontab -
これは、ここで説明する他の回答と簡単に組み合わせることができます。
crontab -l | <something> | tee |crontab -
または、ファイルに内容がある場合はさらに簡単です
cat <file> |crontab -
JohnZの答えに加えて、sudoerである場合にrootとしてスケジュールする構文は次のとおりです。
(Sudo crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | Sudo crontab -
man 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 -
乾杯。
重複を回避する別のワンライナーの方法があります
(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 -
Stdoutをcrontab
にパイピングしてもmacOSに新しいcrontabがインストールされなかったため、代わりにサブシェルでtee
エディターを使用してこのソリューションを見つけました。
(EDITOR=tee && (crontab -l ; echo "@daily ~/my-script.sh" ) | uniq - | crontab -e)