インタラクティブなエディターなしでBashを使用してcronジョブを自動的に作成する方法は?


395

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



5
悲しいことに、ここでのトップの回答のほとんどはcrontabを変更する方法を示しているだけです-かなり安全な方法ですが-全体的に間違ったアプローチだと思います。ファイルを{{cron.d}}にドロップする方が、より安全で簡単な方法です。さらに下を見れば、その方法を説明する(現在)投票数の少ない回答があります。
gregmac

回答:


539

次のように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

cronラインの説明

* * * * * "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


14
あなたは、一時ファイルやmktempを使用する必要があります
パヴェルPolewicz

166
(crontab -l; echo "00 09 * * 1-5 echo hello")| crontabの-
江戸

32
(crontab -l ; echo "00 09 * * 1-5 echo hello") | crontab --江戸の衣服をコピーするのが簡単
WBAR '28

8
私はそれを変更することをお勧めしたい;&&場合ケースに対するセーフガードとしてcrontab -l失敗しました。そう、のように:(crontab -l && echo "0 0 0 0 0 some entry") | crontab -
MacUsers

12
@ MacUsers、crontab -lcrontabがない場合は失敗するため、使用&&すると、スクリプトが最初のエントリをcrontabに追加できなくなります。
JPhi1618 2017

312

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

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

crontab -l現在のcrontabジョブをリストし、catそれをecho印刷し、新しいコマンドをcrontab -印刷し、印刷されたものすべてをcrontabファイルに追加します。新たに行うことで効果を確認できますcrontab -l


3
おかげで、構文を説明できますか、それを説明するURLをポイントできますか?
サイト

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

3
私のために御馳走を働かせます。ユーザーに既存のcrontabがない場合は表示されますが、no crontab for <username>とにかく機能します。
2014年

21
Amazon EC2インスタンスでは機能しません。代わりに、(crontab -l ; echo "00 09 * * 1-5 echo hello") | crontab -機能します。
ステファンBruckert

11
これはUUcatAの候補のようです
2016年

86

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

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

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に新しい行を追加するリスクなしにスケジュールを変更できます

@moeseth:詳しく説明できますか?
MoonCactus 2016

あなたはあなたのコンピュータでそれを試すべきです
moeseth

2
@moeseth:私は明らかに自分のコンピューター(linux)で試しました。私はランダムに機能しないものはお勧めしません:/
MoonCactus

2
ちなみに、27人は間違いではありません(今日)。セットアップで機能しない理由を説明してください。サポートさせていただきます。
MoonCactus 2017

2
OSXの問題かもしれません。
moeseth

40

皆さんの助けに感謝します。私がここで見つけたものと他の場所で見つけたものをつなぎ合わせてこれを思いつきました:

コード

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の功績です。この小さなリダイレクトもの(<(*command*))を使用crontab -lして、fgrepコマンドの出力を入力に変換します。
  2. fgrep次に、$command-vオプション)、大文字と小文字を区別しない(-iオプション)の一致をすべて除外します。
  3. この場合も、小さなリダイレクトThing(<(*command*))を使用して、結果をcatコマンドの入力に戻します。
  4. このcatコマンドecho "$job"は、リダイレクトシングリー(<(*command*))を使用して(自明)も受け取ります。
  5. したがって、フィルター処理された出力crontab -lと単純なecho "$job"を組み合わせてパイプ処理( '|')してcrontab -、最終的に書き込みます。
  6. そして、彼らはみんな幸せに暮らしました!

手短に:

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


5
他の人が読むために、このアプローチの利点は、(他のすべてのソリューションとは異なり)crontabのエントリの重複を心配せずに複数回実行できることです。理由のだというfgrep -v
aleemb

5
:あなたは、物事配管の伝統的な左から右への道を好む場合は、との最後の行置き換える crontab -l | fgrep -i -v "$command" | { cat; echo "$job"; } | crontab -l
アントワーヌLizée

1
@AntoineLizée、あなたが答えると、最後に余分な "l"があります。
Henry

26

編集(固定上書き):

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

これはすべてのcrontabの内容を置き換えます
TheBonsai 2009年

1
@TheBonsaiああ、わかりました。修正しましたので、新しいコマンドを既存のcrontabの内容に
追加し

3
Bashのプロセス置換ではエラーが発生することに注意してください。crontab -l失敗してもcrontab -成功した場合は、crontabが1行になります。
2016年

13

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自体を提供しました。このファイルは実行可能であってはならず、名前には英数字とハイフンのみを含める必要があります(詳細は以下を参照)。

しかし、完全な答えを与えるために、crontabvs の違いを見てみましょうcron/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.dの下のファイルは実行可能である必要はありませんが、/ etc / cron.hourly、/ etc / cron.daily、/ etc / cron.weekly、/ etc / cron.monthlyの下のファイルは実行可能である必要があります。これらはrun-partsによって実行されます(詳細については、run-parts(8)を参照してください)。

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

この方法でcronを管理することは、システムの観点からはより簡単でスケーラブルですが、常に最良のソリューションであるとは限りません。


1
<job>ファイル拡張子を含めないでください。
jww

7

おそらく、これを自動化していて、1つのジョブを2回追加したくないでしょう。その場合は以下を使用してください:

__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の質問で


多分bashの代わりにshを使用していますか?
kvz 2012

まだshsh: 1: Syntax error: "(" unexpectedを使用しています。
Batandwa

これは、BASHを使用している場合にのみ機能します。私は正しいDASH(sh)構文を知りません。回答も更新
kvz

1
FWIW、私は間にスペースがある場合にはbashを使用して、このエラーが出る<とは(。これは< (失敗することを意味しますが<(、スケジュールにアスタリスクがない限り機能します...
doublesharp

私はこれが正しい方法であると信じて:cat <(crontab -l |grep -v "${CRON}") <(echo "${CRON}") | crontab -
スタニスラフ

5

BASHスクリプトを使用してcrontabをすばやく簡単に作成/置換するには、次の表記を使用しました。

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

5

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

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

3

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

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

これを通常のユーザーとして処理する方法がないこと、および多くのcron実装でこれを処理する方法がないことは、cronの悲しい機能です。


2

したがって、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-std outで出力を作成する手段。printf、cat ...も機能します

"-文字列の先頭に二重引用符を使用すると、あなたはプロです

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

ntpdate -u time.nist.gov-実行する実際のコマンド

"-私の最初の二重引用符は、出力されている行を閉じるためにバディを必要とするため

>>-上書きではなく追加の二重リダイレクト*

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


*>リダイレクトを使用した場合、タスクエントリが1つだけであることを保証できます。しかし、既存のファイルにある他のルールを吹き飛ばすリスクがあります。>による破棄の可能性が適切であるか、または>>による重複の可能性が適切かどうかを自分で決定できます。または、ファイル名が存在するかどうか、ファイル名が含まれているかどうか、重複を追加していないかどうかを確認するために、複雑または複雑なことを行うこともできますが、私にはやるべきことがあり、それを行うことはできませんあなたは今。


2

対話型エディターなしで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

1
私はそれが長い間だったことを知っていますが、最も投票されたものはすべて新しいcronを追加するのではなく古いcronを削除するので、これはまだ唯一の良い答えです。
AFE

1
これはcronをインストールしません。ファイルに追加するだけです。新しいエントリをインストールするには、何らかの方法でcronプロセスに通知する必要があります。
Apoorv Parijat

1

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
CRON="1 2 3 4 5 /root/bin/backup.sh" 
cat < (crontab -l) |grep -v "${CRON}" < (echo "${CRON}")

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

cronジョブを追加/削除するスクリプト関数。重複エントリなし:

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

crontabに同じコマンドを2回(異なる時間に実行)した場合、削除すると両方の行が削除されます。
Michaelkay

1

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

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

これにより、下部にある空白の新しい行を正しく処理することができます。crontabの問題を回避するには、通常、空の新しい行でcrontabファイルを終了する必要があります。上記のスクリプトでは、最初に「grep」を使用して空白行を削除します。スクリプトの最後に「\ n」を付けて、最後に新しい空白行を追加します。これにより、既存のcrontabファイルが空白行で終わっている場合、新しいコマンドの上に空白行が表示されることもなくなります。



0

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

現在のcronファイル(crontab -l> newfile)を取得し、それを変更して、新しいファイル(crontab newfile)を配置する必要があります。

perlに精通している場合は、このモジュールConfig :: Crontabを使用できます。

LLP、アンドレア


0

cronjobsを追加するスクリプト関数。重複するエントリ、使用可能な式をチェック*> "

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

ソース:私の脳;)


-5

おそらく、デフォルトのエディターをedに変更し、ヒアドキュメントを使用して編集できます。

EDITOR=ed
export EDITOR

crontab -e << EOF
> a
> * * * * * Myscript
> * * * * * AnotherScript
> * * * * * MoreScript
> .
> w
> q
> EOF

このコードの先頭の>は、Return / Enterキーを押して新しい行を作成することを意味しています。

それは上書きは何もないような手段を追加します。

編集が完了したことを意味します。

ワット手段が変更を書き込みます。

q個の手段は、quitまたはexit編。

あなたはそれをチェックすることができます

crontab -l

エントリを削除することもできます。

EDITOR=ed
export EDITOR

crontab -e << EOF
> /Myscript/
> d
> .
> w
> q
> EOF

Myscriptが含まれているcrontabエントリが削除されます。

Dの手段は、内部のパターンを削除/ /

もう一度チェックしない

crontab -l

このソリューションはスクリプト内で機能しますが、>>もちろんです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.