web-dev-qa-db-ja.com

crontabのパスとユーザー

Cronとcrontabを使用してタスクをスケジュールするのは初めてです。ログオンして端末を開いて自分で実行したかのように、タスクの実行をスケジュールしようとしています。

ただし、スケジュールされたタスクがどの$ 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タスクを希望どおりに実行するには何をする必要がありますか?

47
Adam S

「man 5 crontab」によれば、cron行の前に環境変数を記述することにより、crontabで環境変数を設定できます。

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または環境変数を必要に応じて調整できます。しかし、この例は典型的な場合には十分なようです。

77
Julien Palard

* ixでは、プロセスは通常、fork + execを介して親プロセスから環境を継承します。環境をクリアするオプションがありますが、通常はありません。 ps axfを使用してプロセスツリーを表示でき、ps axfeを使用して環境変数を表示できます。

cronは通常、誰かのシェルの子ではないため、多くの場合、インタラクティブシェルとは異なる環境になります。ただし、cronが一貫性のために何らかの形で意図的に自身の環境をクリアする可能性があります。

対話型シェルで次のコマンドを使用して、cronジョブ(「foo」)をテストします。env-./fooこれにより、cronが実行するenv変数が実際に消去されますが、物事を簡単に取得できますあなたがテストしているものがより似ているので、IMOに行く。依存している変数($ PATHなど)を設定するか、他の変数に置き換える必要があります-EG $ USERは$(whoami)になります。

また、「set -eu」と「set -o pipefail」を使用するbashスクリプトを作成することも好きです。 -euは「ゼロ以外の終了コードで終了し、未定義の変数参照で終了する」を示し、pipefailは「パイプラインの最後の終了コードを返さないで、代わりにパイプラインのゼロ以外の最初の終了コードを返す」を示します。あなたの場合、セット-uが特に役立つかもしれません。

15
user1277476

私たちの環境では、ルートは許可される唯一のcronであり、各コマンドは通常、アプリケーション固有のユーザーVIA a su -cコマンドとして実行されるため、この問題は通常ありません。

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

「-」オプションが指定されているため、myuserのプロファイルと環境を取得します。最近、正常に完了するためにルートの権限を必要とするコマンドに問題があったため、su -cなしでコマンドを発行しました。ある程度の調査の後、ルートの環境を取得する最も簡単な方法は、他のすべてのアプリケーションで行うのと同じ手法をルートに使用することであることがわかりました。

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

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

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

よくわかりませんが、crontabファイル内でアクセスできるのはPATH(および設定した場合はEMAIL)だけかもしれません。

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

1
KurzedMetal