これら2つのcronジョブの何が問題になっていますか?


13

次のcronジョブが定義されています。

55  8   *   *   3   /usr/bin/php /home/mark/dev/processes/customClient/events.php > /home/mark/dev/processes/customClient/events-`date +%Y-%m-%d --date='last Wednesday'`-`date +%Y-%m-%d`.csv
0   9   *   *   3   /usr/bin/echo 'The csv for last week, trying my hand at automatiging this' | /usr/bin/mutt <emailaddress> -s 'Events from `date +%Y-%m-%d --date='last Wednesday'`-`date +%Y-%m-%d`' -a '/home/mark/dev/processes/customClient/events-`date +%Y-%m-%d --date='last Wednesday'`-`date +%Y-%m-%d`.csv'

上記のコマンドをコマンドラインから直接実行すると、正常に動作するようです。しかし、今朝スクリプトの実行を確認したときに、バックティックが適切に閉じられなかったことを示す電子メール(誤って削除したために言い換えています)を受け取りました。


参考までに、cronジョブを再テストしたところ、次のエラーが発生しました。 /bin/sh: 1: Syntax error: EOF in backquote substitution 最初のcronジョブ。 /bin/sh: 1: Syntax error: Unterminated quoted string 2番目のcronジョブ。
マークD

2
この理由から、バックティックは非推奨です。変更すると、$(...)あなたが引用の問題...に対処するのに役立ちます
jasonwryan

1
あなたは間違いなく私の質問をチェックしたいです。Stephane Chazelasによる回答があり、cronジョブが表示する環境と同一の対話型シェルを作成する方法を説明しています。彼の小さな手順を説明すると、プロンプトが表示され、cronjobを段階的にテストして、どこで失敗するかを確認できます。unix.stackexchange.com/a/56503/16841質問と完全に一致するわけではありませんが、crontabの問題のトラブルシューティングに役立ちます。
ジッピー

回答:


14

多くの理由から、重要なcronジョブを独自のシェルスクリプトファイルに入れることを強くお勧めします。

  • デバッグが簡単:長い行をコピーしてコピーする代わりにスクリプトを実行するだけで、正しいシェバン行を使用すると、crontabで直接同じコマンドを実行した場合よりもはるかに予測可能な動作をします
  • 読みやすく:200文字以上のワンライナーにする必要はありません。きれいにフォーマットできるので、誰でも簡単に読んで理解できます。
  • スクリプトをバージョン管理に追加する

8
そして、面倒%な文字をスクリプトに入れると、文字がcron改行にならないようになります。これが本当の問題です。
イアンD.アレン

同意しません。どのスクリプトが何をするかを忘れがちです。私は経験から話しています。
スリダールサルノバト

30

cronジョブコマンドの一般的な原因として、対話型シェルに直接入力されたコマンドとは異なる動作をする3つの一般的な原因があります。

  • Cronは、最小限の環境$PATH、およびその他の予期される変数が欠落しているなど、限られた環境を提供します。
  • Cronは/bin/shデフォルトで起動しますが、他のシェルをインタラクティブに使用している場合があります。
  • Cronはその%文字を特別に扱います(コマンドで改行に変換されます)。
  • Cronは端末環境またはグラフィカル環境を提供しません。

crontabファイルでは、すべての%文字の前\にaを付ける必要があります。これは、コマンドにパーセントを入れるようにcronに指示します。datecronジョブでコマンドを使用するときは覚えておいてください。

55  8   *   *   3   /usr/bin/php /home/mark/dev/processes/customClient/events.php > "/home/mark/dev/processes/customClient/events-$(date +\%Y-\%m-\%d --date='last Wednesday')-$(date +\%Y-\%m-\%d).csv"
0   9   *   *   3   /usr/bin/echo 'The csv for last week, trying my hand at automatiging this' | /usr/bin/mutt <emailaddress> -s "Events from $(date +\%Y-\%m-\%d --date='last Wednesday')-$(date +\%Y-\%m-\%d)" -a "/home/mark/dev/processes/customClient/events-$(date +\%Y-\%m-\%d --date='last Wednesday')-$(date +\%Y-\%m-\%d).csv"

引用の問題も修正しました。

  • これは読みやすさ以外の問題を引き起こしていませんでしたが、コマンドの置換にバッククォートを使用するべきではありません。$(…)代わりに使用してください:その解析規則はより単純です。
  • 変数とコマンドの置換には常に二重引用符を使用します:"$somevariable""$(somecommand)"。ここでは、dateコマンドが使用した形式に対して特殊文字を返さないため、引用符がなくても問題はありませんが、どの文字が特殊であるかを慎重に覚えて、置換を引用符で囲まずに残すたびにこれを確認する必要があります。結果をフィールド分割とファイル名生成が発生するようにしたい場合を除き、シンプルに保ち、常に二重引用符を使用します。
  • いくつかのコマンド置換の周りの展開を妨げる単一引用符がありました。代わりに二重引用符を使用してください。

0

コマンドにネストさ'れているようですmutt

'からのイベントdate +%Y-%m-%d --date='last Wednesday'- date +%Y-%m-%d'

ステートメントが読み取るよう"に、内部の代わりに使用してみてください'

'からのイベントdate +%Y-%m-%d --date="last Wednesday"- date +%Y-%m-%d'


それが問題なのかわかりません。しかし、両方のcronジョブで試してみると、成功せずに実行されます。
マークD
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.