crontabエントリに7つのエントリがあるとはどういう意味ですか?

crontabエントリに7つのエントリがあるとはどういう意味ですか?

一部の同僚は、クローンタスクを追加してタスクを実行しますが、次の行を実行してcrontab -e追加することを提案しました。

 0 1 * * * . /path/to/some/file.bash

この機能が機能していることを確認するために、次のように変更しました。

 0 1 * * * . /path/to/some/file.bash && date >> /some/log

/some/logこれにより、毎日行がなくなったことを確認できます。

しかし、そのようなことは起こりませんでした。

デバッグ目的で、次の3行をに追加しましたcrontab -e

 * * * * * echo "uffa" >> /home/me/without-user
 * * * * * me echo "uffa" >> /home/me/with-user
 * * * * * . echo "uffa" >> /home/me/with-any-user

私のユーザー名はどこにありますかme?これにより、3つのファイルがすべて作成されますが、8分後に実行した確認に示すように、最初のファイルだけが1分ごとに1行ずつ増えます。

$ for f in ~/with*; do echo ''; echo $f; cat $f; done

/home/emdeange/with-any-user

/home/emdeange/without-user
uffa
uffa
uffa
uffa
uffa
uffa
uffa
uffa

/home/emdeange/with-user

どうしたの?行に追加のエントリがあるため、行2と3は間違った構文を使用していますか?それでは、なぜファイルは生成されたのでしょうか?


このような不可解なコマンドを実行すると、次の2行を知らせる空が生成されることjflkdasjflaksd > someFileを確認しました。someFile

 * * * * * me echo "uffa" >> /home/me/with-user
 * * * * * . echo "uffa" >> /home/me/with-any-user

それは間違っているだけで、シェルのコマンドライン処理がどのように機能するかによってエラーが発生する前にファイルが生成されます。

しかし、これは他の人に役立つ可能性がある行です。何が問題なの?

答え1

さて、まず少し異なる2crontabつの形式があります。 1つはユーザー固有のcrontab用、もう1つはシステムcrontab(/etc/crontabおよびその中のファイル/etc/cron.d/)用です。

パーソナルcrontabには、時刻と日付を入力する5つのフィールドがあり、残りはコマンドを入力するフィールドがあります。システムcrontabには5つの時間と日付フィールドがあります。6番目は、ユーザーがコマンドを実行することです。、残りのコマンド。合計6個と7個です。コマンドの最後の「フィールド」は、他のフィールドとは若干異なって定義されます。

パーソナルcrontabにはユーザー名フィールドはありません。 crontabは所有者が誰であるかを暗示し、一般ユーザーは他の人のようにプログラムを実行できないためです。

(コメントで指摘したように、ユーザーのプライベートクローンタブも他のユーザーと同様にプライベートクローンタブです。他の点では少し特別ですが、ユーザー名rootフィールドはありません。もあります)。root/etc/crontabcrontab -e


その後、.シェルに引数と呼ばれるスクリプトを読み、実行するように指示します。現在のシェルから(一部のシェルで呼び出されるsourceエイリアス.)スクリプトを別のプログラムとして実行する場合とは異なり、すべての関数定義と変数の割り当ては後で表示されます。

ライン

0 1 * * * . /path/to/some/file.bash

cron で始まるシェルを.../file.bash同じシェルで実行するように指示します。ドットなしでコマンドを実行するのではなく、なぜこれを推奨するのかわかりません。新しいシェルを初期化する必要がないことは少し最適化されるかもしれませんが、スクリプトをcron起動シェルで実行する必要があるという欠点があります。 cronは通常のshを起動しますが、スクリプトはzshまたはPython用の場合は機能しません。

この行がグローバルcrontabにある場合は、/path/to/some/file.bashuserとして実行されます.。おそらくそういう意味ではないでしょう。

簡単にするために、以下をお勧めします(スクリプトを実行可能にし、まだ実行していない場合は適切なハッシュバン行を追加した後)。

0 1 * * * /path/to/some/file.bash

それでも. /some/script && date >> logfile動作しない場合は、まずスクリプトがエラーで終了することを確認してください。&&ここでは、左側のコマンドが正常に終了した場合にのみ右側のコマンドを実行するようにシェルに指示する演算子を使用しました。. /some/script; date >> logfile無条件に実行してください。あるいは、. /some/script; printf "run at %s, exit status %d\n" "$(date)" "$?" >> logfile終了ステータスを保存してみることもできます。


これらについては:

* * * * * echo "uffa" >> /home/me/without-user
* * * * * me echo "uffa" >> /home/me/with-user
* * * * * . echo "uffa" >> /home/me/with-any-user

プライベートcrontabでは、最初のものはシェルに実行するように指示しecho、2番目はシェルにというコマンドを実行するように指示し、3番目はシェルにというスクリプトを実行するように指示しmeますecho。これらのすべてにはリダイレクトが含まれており、コマンドの開始前にリダイレクトがシェルで処理されるため、すべての場合にファイルが生成されます。 (シェルはコマンドを試みる前にコマンドが実行可能かどうかを知ることができず、成功すると制御がコマンドに渡されるため、シェルはこれ以上リダイレクトを介して何もできないため、この方法でなければなりません。)

後者の2つはエラーメッセージを表示できます。クローンが正しく設定されていると、電子メールでエラーメッセージが表示されます。


しかし、これは他の人に役立つ可能性がある行です。何が問題なの?

上記のように、. /path/to/some/scriptシェルで指定されたスクリプトを実行しようとすると、バイナリコマンドが失敗するため、. echo ...機能する可能性はありません。0 1 * * * username echo ...これはグローバルcrontabでは機能しますが、プライベートcrontabでは機能しない可能性があります。有効なユーザー名ではない可能性があるため、0 1 * * * . whatever世界中で機能する可能性はありません。.

答え2

ユーザー名のない最初の行は、ユーザーが所有するcrontabの構文です。

min hour dayofmonth month dayofweek command ...

2行目(ユーザー名を含む)の構文は次のとおりです/etc/crontab

min hour dayofmonth month dayofweek username command ...

3行目が間違っています。技術的には、dotコマンドはechoというファイルからスクリプトを取得し、uffaをパラメータに設定します。スクリプトecho私のシステムではバイナリ /usr/bin/echoそれを取得しようとするとエラーが発生します。

...$ LANG=C . echo
bash: .: /usr/bin/echo: cannot execute binary file

システムログを見ると、cronデーモンでこのエラーメッセージが表示されます。

関連情報