一部の同僚は、クローンタスクを追加してタスクを実行しますが、次の行を実行して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/crontab
crontab -e
その後、.
シェルに引数と呼ばれるスクリプトを読み、実行するように指示します。現在のシェルから(一部のシェルで呼び出されるsource
エイリアス.
)スクリプトを別のプログラムとして実行する場合とは異なり、すべての関数定義と変数の割り当ては後で表示されます。
ライン
0 1 * * * . /path/to/some/file.bash
cron で始まるシェルを.../file.bash
同じシェルで実行するように指示します。ドットなしでコマンドを実行するのではなく、なぜこれを推奨するのかわかりません。新しいシェルを初期化する必要がないことは少し最適化されるかもしれませんが、スクリプトをcron起動シェルで実行する必要があるという欠点があります。 cronは通常のshを起動しますが、スクリプトはzshまたはPython用の場合は機能しません。
この行がグローバルcrontabにある場合は、/path/to/some/file.bash
userとして実行されます.
。おそらくそういう意味ではないでしょう。
簡単にするために、以下をお勧めします(スクリプトを実行可能にし、まだ実行していない場合は適切なハッシュバン行を追加した後)。
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デーモンでこのエラーメッセージが表示されます。