web-dev-qa-db-ja.com

対話型エディタを使わずにBashを使って自動的にcronジョブを作成する方法

Crontabには、エディターを使用せずにcronジョブを作成するための引数があります(crontab -e)。もしそうなら、コードはBashスクリプトからcronjobを作成するのでしょうか?

334
Raúl Roa

次のようにcrontabに追加することができます。

#write out current crontab
crontab -l > mycron
#echo new cron into cron file
echo "00 09 * * 1-5 echo hello" >> mycron
#install new cron file
crontab mycron
rm mycron

クロンラインの説明

* * * * * "command to be executed"
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)

出典 nixCraft

477
dogbane

その場でそれを行うことができるかもしれません

crontab -l | { cat; echo "0 0 0 0 0 some entry"; } | crontab -

crontab -lは現在のcrontabジョブを一覧表示し、catはそれを印刷し、echoは新しいコマンドを印刷し、crontab -は印刷されたものすべてをcrontabファイルに追加します。あなたは新しいcrontab -lをすることによって効果を見ることができます。

284
TheBonsai

この短いファイルは一時ファイルを必要としません。複数の挿入の影響を受けず、既存のエントリのスケジュールを変更できます。

あなたがこれらを持っているとしましょう:

croncmd="/home/me/myfunction myargs > /home/me/myfunction.log 2>&1"
cronjob="0 */15 * * * $croncmd"

複製せずにcrontabに追加するには:

( crontab -l | grep -v -F "$croncmd" ; echo "$cronjob" ) | crontab -

現在のスケジュールにかかわらず、crontabから削除するには

( crontab -l | grep -v -F "$croncmd" ) | crontab -

ノート:

  • grep -Fは、文字列を正規表現として解釈したくないので、文字列と文字通りに一致します。
  • また、タイムスケジューリングを無視してコマンドのみを探します。こちらです; crontabに新しい行を追加するリスクなしにスケジュールを変更できます。
66
MoonCactus

ご協力ありがとうございました。私がここで見つけたものと他の場所で一緒に見つけたものをまとめると:

コード

command="php $INSTALL/indefero/scripts/gitcron.php"
job="0 0 * * 0 $command"
cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -

私は自分自身を繰り返すことなしに2つの変数の必要性を排除する方法を理解することができませんでした。

commandは明らかに私がスケジュールしたいコマンドです。 job$commandを取り、スケジューリングデータを追加します。私は仕事をするコードの行で両方の変数を別々に必要としました。

詳細

  1. Duckyflipに敬意を表したいのですが、crontab -lの出力をfgrepコマンドの入力に変換するために、このちょっとしたリダイレクト(<(*command*))を使います。
  2. fgrepは、$command-v option)の一致を、大文字と小文字を区別しない(-i option)から除外します。
  3. 繰り返しますが、小さなリダイレクト(<(*command*))を使用して、結果をcatコマンドの入力に戻します。
  4. catコマンドもまた、リダイレクト物(<(*command*))を使用してecho "$job"(自明)を受け取ります。
  5. そのため、crontab -lからのフィルタリングされた出力と単純なecho "$job"を組み合わせて、最終的に書き込まれるようにcrontab -にパイプ( '|')されます。
  6. そして彼らは皆、その後も幸せに暮らしていました!

手短に:

このコード行は、コマンドに一致するすべてのcronジョブを除外してから、残りのcronジョブを新しいジョブで書き出して、実質的に「追加」または「更新」機能のように機能します。これを使用するには、command変数とjob変数の値を交換するだけです。

38
Stoutie

EDIT(上書き修正):

cat <(crontab -l) <(echo "1 2 3 4 5 scripty.sh") | crontab -
24
duckyflip

Crontabの使用に関して多くの良い答えがありましたが、cronの使用のようなより単純な方法についての言及はありません。

cronを使用すると、/etc/crontab/etc/cron.daily,weekly,hourlyまたは/etc/cron.d/にあるシステムファイルおよびディレクトリを利用できます。

cat > /etc/cron.d/<job> << EOF
Shell=/bin/bash 
PATH=/sbin:/bin:/usr/sbin:/usr/bin 
MAILTO=root HOME=/  
01 * * * * <user> <command>
EOF

上記の例では、/etc/cron.d/にファイルを作成し、コマンドを正常に実行するための環境変数と、コマンドのuser、およびcommandを指定しました。このファイルは実行可能であってはならず、名前は英数字とハイフンのみを含むべきです(詳細は下記)。

徹底的な答えを与えるために、crontabcron/crondの違いを見てみましょう。

crontab -- maintain tables for driving cron for individual users

システム上で自分のユーザーのコンテキストでジョブを実行したい人にとっては、crontabを使用するのが完全に理にかなっているかもしれません。

cron -- daemon to execute scheduled commands

構成管理を使用している、または他のユーザーのジョブを管理したい人のために、その場合はcronを使用するべきです。

マンページから簡単に抜粋して、何をし、何をしないかの例をいくつか紹介します。

/ etc/crontabと/etc/cron.d内のファイルは、rootが所有している必要があり、グループ書き込みやその他の書き込みができないようにする必要があります。スプール領域とは対照的に、/etc/cron.dの下のファイル、または/etc/cron.hourly、/ etc/cron.daily、/ etc/cron.weekly、および/etc/cron.monthlyの下のファイルも、シンボリックリンクとそれが指すファイルの両方がrootによって所有されている場合。 /etc/cron.dh、/etc/cron.daily、/etc/cron.weekly、および/etc/cron.monthlyの下のファイルは、実行可能である必要はありません。それらはrun-partsによって実行されます(詳細についてはrun-parts(8)を参照してください)。

出典:http://manpages.ubuntu.com/manpages/trusty/man8/cron.8.html

この方法でクローンを管理することはシステムの観点からはより簡単でよりスケーラブルですが、常に最善の解決策とは限りません。

11
Mike Mackintosh

たぶん、あなたはこれを自動化しています、そして、あなたは単一の仕事を二度追加したくないでしょう。その場合は以下を使用してください。

__cron="1 2 3 4 5 /root/bin/backup.sh"
cat <(crontab -l) |grep -v "${__cron}" <(echo "${__cron}")

これはBASHを使用している場合にのみ機能します。正しいDASH(sh)構文がわかりません。

更新:ユーザーがまだcrontabを持っていない場合は機能しません。より信頼性の高い方法は次のようになります。

(crontab -l ; echo "1 2 3 4 5 /root/bin/backup.sh") | sort - | uniq - | crontab - 

あるいは、あなたのディストリビューションがそれをサポートしているのなら、別のファイルを使うこともできます。

echo "1 2 3 4 5 /root/bin/backup.sh" |Sudo tee /etc/crond.d/backup

別のSO質問 でそれらを見つけました。

7
kvz

目的の文字列が見つからない場合にのみcrontabを編集するバリアントです。

CMD="/sbin/modprobe fcpci"
JOB="@reboot $CMD"
TMPC="mycron"
grep "$CMD" -q <(crontab -l) || (crontab -l>"$TMPC"; echo "$JOB">>"$TMPC"; crontab "$TMPC")
5
Gerald Schade

BASHスクリプトからのcrontabのすばやく汚い作成/置き換えのために、私はこの記法を使いました:

crontab <<EOF
00 09 * * 1-5 echo hello
EOF
4
Gibbsoft

Vixie Cronを使用している場合は、ほとんどのLinuxディストリビューションでは、個々のcronjobを付けて/etc/cron.dにファイルを置くだけです。

これはもちろん根本的にしか機能しません。あなたのシステムがこれをサポートしているなら、そこにいくつかの例があるはずです。 (行に含まれているユーザー名が古い/ etc/crontabと同じ構文で含まれていることに注意してください)

Cronでは、これを通常のユーザーとして処理する方法がないこと、および非常に多くのcron実装でこれを処理する方法がまったくないことが残念です。

3
chuck

対話型エディタなしでcronジョブを追加するためのbashスクリプト。以下のコードは、Linuxファイルを使用してcronjobを追加するのに役立ちます。

#!/bin/bash

cron_path=/var/spool/cron/crontabs/root

#cron job to run every 10 min.
echo "*/10 * * * * command to be executed" >> $cron_path

#cron job to run every 1 hour.
echo "0 */1 * * * command to be executed" >> $cron_path
2
akash

これは、複製なしでcrontabにコマンドを追加するためのbash関数です。

function addtocrontab () {
  local frequency=$1
  local command=$2
  local job="$frequency $command"
  cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -
}
addtocrontab "0 0 1 * *" "echo hello"
1
Klas Mellbourn
CRON="1 2 3 4 5 /root/bin/backup.sh" 
cat < (crontab -l) |grep -v "${CRON}" < (echo "${CRON}")

-wパラメータを指定せずにgrep exactコマンドに-wパラメータを追加し、cronジョブ "testing"を追加しないとcronジョブ "testing123"が削除されます。

cronjobを追加/削除するためのスクリプト関数。重複エントリはありません。

cronjob_editor () {         
# usage: cronjob_editor '<interval>' '<command>' <add|remove>

if [[ -z "$1" ]] ;then printf " no interval specified\n" ;fi
if [[ -z "$2" ]] ;then printf " no command specified\n" ;fi
if [[ -z "$3" ]] ;then printf " no action specified\n" ;fi

if [[ "$3" == add ]] ;then
    # add cronjob, no duplication:
    ( crontab -l | grep -v -F -w "$2" ; echo "$1 $2" ) | crontab -
Elif [[ "$3" == remove ]] ;then
    # remove cronjob:
    ( crontab -l | grep -v -F -w "$2" ) | crontab -
fi 
} 
cronjob_editor "$1" "$2" "$3"

テスト済み:

$ ./cronjob_editor.sh '*/10 * * * *' 'echo "this is a test" > export_file' add
$ crontab  -l
$ */10 * * * * echo "this is a test" > export_file
1
speefak

それで、Debian、Ubuntu、そして多くの同様のDebianベースのディストリビューションでは...

設定ファイルを受け取り、それらをまとめて、実行中のcronサービスに追加するcronタスク連結メカニズムがあります。

ファイルを/etc/cron.d/somefilenameの下に置くことができます。ここで、somefilenameは必要なものです。

Sudo echo "0,15,30,45 * * * * ntpdate -u time.nist.gov" >> /etc/cron.d/vmclocksync

これを分解しましょう。

Sudo - /etcディレクトリの下のcron設定を変更するには昇格された特権が必要です

echo - 標準出力に出力を作成する手段printf、cat ...でもうまくいく

" - 文字列の先頭に二重引用符を使用してください。あなたはプロです。

0、15、30、45 * * * * - 標準のcron実行スケジュール。これは15分ごとに実行されます。

ntpdate -u time.nist.gov - 実行したい実際のコマンド

" - 最初の二重引用符は出力されている行を閉じるために友達が必要です

>> - 上書きの代わりに二重リダイレクトが追加されます*

/etc/cron.d/vmclocksync - vmclocksyncは私が選択したファイル名で、/etc/cron.d/にあります。


*リダイレクトを使用した場合、タスクエントリが1つしかないことを保証できます。しかし、既存のファイル内の他の規則がすべて破壊される危険があります。 >での破壊の可能性が正しいのか、>>での重複の可能性があなたのためであるのかを自分で決めることができます。別の方法として、ファイル名が存在するか、何かがあるかどうか、そして何らかの種類の複製を追加しようとしているかどうかを確認するために、複雑または複雑なことを行うことができますあなたは今.

0
BradChesney79

cronjobを追加するスクリプト関数重複したエントリ、使用可能な表現をチェックしてください*> "

cronjob_creator () {         
# usage: cronjob_creator '<interval>' '<command>'

  if [[ -z $1 ]] ;then
    printf " no interval specified\n"
Elif [[ -z $2 ]] ;then
    printf " no command specified\n"
else
    CRONIN="/tmp/cti_tmp"
    crontab -l | grep -vw "$1 $2" > "$CRONIN"
    echo "$1 $2" >> $CRONIN
    crontab "$CRONIN"
    rm $CRONIN
fi
}

テスト済み:

$ ./cronjob_creator.sh '*/10 * * * *' 'echo "this is a test" > export_file'
$ crontab  -l
$ */10 * * * * echo "this is a test" > export_file

出典:私の脳;)

0
user8555334

これに対する私の好ましい解決策はこれでしょう:

(crontab -l | grep . ; echo -e "0 4 * * * myscript\n") | crontab -

これにより、下部の空白の新しい行を正しく処理していることを確認できます。 crontabに関する問題を回避するには、通常、crontabファイルを空白の新しい行で終了します。そして上記のスクリプトは、最初に "grep"で空白行を削除することを確認します。 partをクリックし、最後にスクリプトの最後に "\ n"を付けて新しい空白行を追加します。これにより、既存のcrontabファイルの末尾が空白行になっても、新しいコマンドの上に空白行が表示されなくなります。

0
gsus

いいえ、crontabにはcronファイルを変更するオプションはありません。

現在のcronファイル(crontab -l> newfile)を取り、変更して新しいファイルを配置します(crontab newfile)。

Perlに慣れているなら、このモジュール Config :: Crontab を使うことができます。

LLP、アンドレア

0
andcoz
echo "0 * * * * docker system Prune --force >/dev/null 2>&1" | Sudo tee /etc/cron.daily/dockerprune
0
user11547308