2012-04-12 6 views
41

私はcronとcrontabでタスクをスケジューリングするのが初めてです。あたかも私がログオンして、端末を開いて、自分で実行したかのように、タスクの実行をスケジュールしようとしています。crontab PATHとUSER

はしかし、私は私がスケジュールされたタスクがで実行されているものを$ USERおよび$ PATH観察を支援するタスクをスケジュールし、そしてこれは私が見つけたものです:

$ crontab -l 
41 11 * * * echo "USER: $USER" > ~/Desktop/cron_env.log; echo "PATH: $PATH" >> ~/Desktop/cron_env.log 
$ cat ~/Desktop/cron_env.log 
USER: 
PATH: /usr/bin:/bin 

の$ USERが設定されていないかのようにそれが表示されます$ PATHは非常に基本的なもので、デフォルトのものです。逆に、これは私が(ログイン)ターミナルを開き、この同じ情報をエコーするとき、私が見たものである。

USER: aschirma 
PATH: /usr/lib/jvm/java-6-sun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/pkg/icetools/bin:/pkg/hwtools/bin:/pkg/netscape/bin:/pkg/gnu/bin 

私は私のcrontabのタスクは、私が好きな方法を実行するために行うには何が必要ですか?

答えて

0

crontabはbashスクリプトではありません。通常、シェルで使用できる環境変数は使用できません。

すべてのコードをshebang'edスクリプトファイル(行 "#!/ bin/bash"で始まる)に移動し、そのスクリプトをcrontabで実行してみてください。

私は確信していませんが、私はあなたがcrontabファイルの中でアクセスできる唯一のものかもしれないPATH(と設定した場合、おそらくEMAIL)だと思います。

編集:crontab 5 man pageをチェックしてください。かなりの環境変数があり、すべてがcronデーモンによって設定されています。

+0

OPを:研究のいくつかの量の後、それは根の環境を取得する最も簡単な方法は、我々がそうであるように、我々は発行されて、他のすべてのアプリケーションのルートに同じ技術を使用することであることを私たちに夜が明けました。 cronから起動されたスクリプトは正しいPATHを継承していません。実際には、それは私が最初に問題にぶつかり始めたところです:PATHが正しくないので、cronから実行されたbashスクリプトはPATH内のものを見つけられませんでした。 –

+0

@AdamSそれは問題です、彼らはあなたのログインシェルから取得したものと同じではないcronデーモンによって与えられたPATH(および他のいくつかの変数)を継承します。もし必要ならcrontabファイルにPATHを設定できます。 – KurzedMetal

+0

マンページから: '環境変数の置換や置換のために値の文字列が解析されないため、PATH = $ HOME/bin:$ PATHのような行は期待通りに機能しません。 ' – blujay

4

crontabはデーモンやサービスなので、ログインしたユーザーなどとは異なります。環境変数を設定したい場合は、自分で設定する必要があります。しかし、これらの変数のほとんどは、シェルによって/ etc/profileパスから設定され、カスタム変数に$ HOMEディレクトリに入ります。 cron_env.shのようなものが含まれます

 
41 11 * * * /home/<me>/cron_env.sh 
:あなたが好きな「ソーシング」あなたは/ etc/profileでそれらのいくつかを設定することができるかもしれ

*のIXに

 
#!/bin/sh 
source /etc/profile 
/usr/bin/env > /home/<me>/cron_env.log 

+0

上記はすべて私のために働かなかった、私はちょうど私のbashファイルのソースを追加し、それは働いた!ありがとう –

15

を、プロセスが一般から環境を継承しますfork + exec全体の親プロセス。彼らには環境をクリアするオプションがありますが、通常はそうしません。 ps axfを使ってプロセスツリーを見ることができ、ps axfeを使って環境変数を見ることができます。

cronは通常、他のシェルの子ではないため、対話シェルとは異なる環境を持つことがよくあります。 cronは意図的に一貫性を保つために自分の環境を意図的にクリアする可能性があります。

私はインタラクティブシェルで次のように私のcronジョブ(議論のために「foo」を)テストする: ENV - ./foo これ以上出ます実際に明確なenvがcronのがないことvarsは、それあなたがテストしているものがより似ているので、IMOに行くのが簡単になります。依存する変数を設定する必要があります($ PATHなど)。あるいは、他の変数に置き換える必要があります.EG $ USERは$(whoami)になります。

「set -eu」と「set -o pipefail」を使用するためのbashスクリプトを作成することもできます。 -euは「0以外の終了コードで終了し、未定義の変数参照で終了する」と言っていますが、パイプフェイルでは「パイプラインで最後の終了コードを返しません。 。あなたの場合、set -uは特に役立つかもしれません。

+1

+1のためのテスト...私は 'env''d単一ダッシュについての情報を見つけることを探している。私はそれが '-i、--ignore-environment'行に含まれていたことを、記述セクションの最後の部分ではなく、私が完全にそれを見ていた場所にするのではなく、 –

66

"man 5 crontab"によれば、crontabの環境変数は、cron行の前に書くことで設定できます。

あなたはそれをコピー/ペーストする必要がありますのでcrontabファイルの例もあります:

$ man 5 crontab | grep -C5 PATH | tail 
# and files in /etc/cron.d. These files also have username fields, 
# that none of the other crontabs do. 

SHELL=/bin/sh 
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 

# m h dom mon dow usercommand 
17 * * * * root cd/&& run-parts --report /etc/cron.hourly 
25 6 * * * root test -x /usr/sbin/anacron || (cd/&& run-parts --report /etc/cron.daily) 
47 6 * * 7 root test -x /usr/sbin/anacron || (cd/&& run-parts --report /etc/cron.weekly) 

だから、あなたが欲しいものは何でもあなたのPATHまたはいずれかの環境変数を調整することができます。しかし、この例は、典型的なケースでは十分であるようです。私たちの環境では

+6

'PATH = $ PATH:/ usr/local/bin'のようにする方法はありますか? – CMCDragonkai

+4

@CMCDragonkai: 'man 5 crontab'によると、"値の文字列は、変数の環境置換や置換のために解析されません "。しかし、あなたはおそらく単一の実行可能ファイル( '.sh'は普通はPythonではないのですが?)にコードを書き、crontabから実行ファイルを呼び出し、実行ファイルに$ PATHを追加させるべきです。 –

+0

これは私のためにhttps://community.letsencrypt.org/t/letsencrypt-renew-not-working-with-cronjob-manually-it-works/16738/8を解決しました。 –

2

ルートが許される唯一のcronであり、各コマンドは、通常通りのsu -cコマンドを介して、アプリケーション固有のユーザーとして実行されるよう、私たちは一般的にこの問題を持っていない:ので、

su - myuser -c "/usr/local/scripts/app.sh" 2>&1 

は、 myuserのプロファイルと環境を取得するための " - "オプションが指定されています。私たちは最近、rootの権限を必要とするコマンドに問題があったので、su -cを付けずにコマンドを発行しました。ここ

su - root -c "/usr/local/scripts/app.sh" 2>&1