crontabが使用する環境変数はどこに設定できますか?


266

私は毎時間crontabを実行しています。それを実行して.bash_profileいるユーザーは、ユーザーが端末からジョブを実行するときに動作する環境変数を持っていますが、実行時にcrontabによって取得されないことは明らかです。

私はそれらを設定しようとした.profile.bashrc彼らはまだピックアップを取得していないようです。crontabが取得できる環境変数をどこに配置できるか、誰か知っていますか?

回答:


88

コマンドを実行する前に、「cron」で環境を設定するシェルスクリプトを実行してください。

常に。

#   @(#)$Id: crontab,v 4.2 2007/09/17 02:41:00 jleffler Exp $
#   Crontab file for Home Directory for Jonathan Leffler (JL)
#-----------------------------------------------------------------------------
#Min     Hour    Day     Month   Weekday Command
#-----------------------------------------------------------------------------
0        *       *       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/hourly
1        1       *       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/daily
23       1       *       *       1-5     /usr/bin/ksh /work1/jleffler/bin/Cron/weekday
2        3       *       *       0       /usr/bin/ksh /work1/jleffler/bin/Cron/weekly
21       3       1       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/monthly

〜/ bin / Cron内のスクリプトはすべて、次のような単一のスクリプト 'runcron'へのリンクです。

:       "$Id: runcron.sh,v 2.1 2001/02/27 00:53:22 jleffler Exp $"
#
#       Commands to be performed by Cron (no debugging options)

#       Set environment -- not done by cron (usually switches HOME)
. $HOME/.cronfile

base=`basename $0`
cmd=${REAL_HOME:-/real/home}/bin/$base

if [ ! -x $cmd ]
then cmd=${HOME}/bin/$base
fi

exec $cmd ${@:+"$@"}

(古いコーディング標準を使用して書かれています-最近では、最初にシバン '#!'を使用します。)

「〜/ .cronfile」は、cronで使用するための私のプロファイルのバリエーションです-厳密に非インタラクティブであり、騒々しいためにエコーしません。代わりに.profileなどを実行するように手配できます。(REAL_HOMEのものは私の環境のアーティファクトです-$ HOMEと同じであると偽ることができます。)

したがって、このコードは適切な環境を読み取り、ホームディレクトリからコマンドの非cronバージョンを実行します。したがって、たとえば、「weekday」コマンドは次のようになります。

:       "@(#)$Id: weekday.sh,v 1.10 2007/09/17 02:42:03 jleffler Exp $"
#
#       Commands to be done each weekday

# Update ICSCOPE
n.updics

'daily'コマンドの方が簡単です。

:       "@(#)$Id: daily.sh,v 1.5 1997/06/02 22:04:21 johnl Exp $"
#
#       Commands to be done daily

# Nothing -- most things are done on weekdays only

exit 0

246

crontab -eコマンドラインから実行する場合、crontab自体で環境変数を定義できます。

LANG=nb_NO.UTF-8
LC_ALL=nb_NO.UTF-8
# m h  dom mon dow   command

* * * * * sleep 5s && echo "yo"

この機能は、cronの特定の実装でのみ使用できます。UbuntuとDebianは現在、vixie-cronを使用しており、これらをcrontabファイル(GNU mcronという)で宣言できます。

ArchlinuxRedHat 、環境変数を宣言できないcronieを使用しており、cron.logに構文エラーをスローします。回避策はエントリごとに実行できます。

# m h  dom mon dow   command
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"

58
シェルのように変数置換を使用できないため、PATH = / usr / local / bin:$ PATHのような宣言は文字どおりに解釈されます。
Zac

8
RedHat 4.4.7-3およびcronie-1.4.4-15.el6.x86_64の下でcrontab自体に環境変数を設定することができました
Bruno Lange

7
変数がコマンド内でのみ使用されている場合は、変数をエクスポートする必要はありません。コマンドの前に追加するだけです。"* * * * * sleep 5s; LC_ALL = nb_NO.UTF-8 echo $ LC_ALL"
vutran


@BrunoLangeでは、どのようにしてそれらを設定したのですか?
Newskooler

145

私はこの問題のもう一つの解決策を得ました:

0 5 * * * . $HOME/.profile; /path/to/command/to/run

この場合、$HOME/.profileファイルで定義されているすべての環境変数が選択されます。

もちろん$HOME、これも設定されていません$HOME。これをの完全なパスに置き換える必要があります。


これは、答えを見つけるために多くの苦労した後、私にとってはうまくいきました、ありがとう!
vladimir montealegre 2012

5
$ HOMEの前の期間を省略したことに気づくまで、これは私にとってはうまくいきませんでした。正確には、その期間は何をしますか?
flymike 2013年

9
ピリオドは「ソース」コマンドと同等です:tldp.org/LDP/abs/html/special-chars.html#DOTREF
Jeff W

@PeterLee言及されたものはあなたのために機能しましたか?これは、上記の解決策では効果がなかったためです。上記の解決策が機能しない場合、理由を見つけるためにいくつかの調査を行う必要があります。;-)
Vishal

3
@Vishal実は、今はうまくいきます。私がしようとしsource ~/.bashrcていましたが、私の.bashrcファイルがcronジョブとある程度競合していることがわかりました。.env_setup_rc1行のみの非常に単純なファイルを使用すると、export MY_ENV_VAR=my_env_val実際に機能します。私のポストを参照してください。stackoverflow.com/questions/15557777/...
ピーター・リー

63

varsの設定/etc/environmentもUbuntuではうまくいきました。12.04以降、の変数は/etc/environmentcron用にロードされます。


11
ベストアンサー。実行するだけでenv >> /etc/environment、現在のすべての環境変数がCRONジョブで使用できるようになりました。
サベージマン2016年

6
これは私にとってはうまくいきます。特に私はDockerコンテナーを実行しているので、「システム全体」の影響についてはあまり気にしません。
Lucas Pottersky、2016年

14
@Savagemanは核融合爆弾でハエを殺すようなものですが、予期しない動作の危険も非常に高くなっています。
Fran Marzoa

2
注意してください:env >> /etc/environment環境変数の1つにハッシュ記号があると失敗します。アプリケーションのトラブルシューティングに最も苦労しました。そのステップで切り捨てられていた「#」を含むパスワードであることが判明しました。
asac

3
これが選ばれた答えであるべきです。なぜ人々が他の答えやenv >> / etc / environmentに関するこの問題で複雑になっているのかわかりません。これらの環境変数を広く使用できるようにするには、etc / environmentを適切に点滅させるだけです。私の実験では、/ etc / environment内の環境変数のエクスポートステートメントがcrontabでもユーザーでも使用できることを確認しているようです。問題:再び私の実験から:これらの環境変数はcrontab自体の中で拡張されていないようです!...つまり、呼び出されたスクリプトでのみ展開されます!
マイクげっ歯類

39

cronを介して実行しているスクリプトを次のように開始すると、

#!/bin/bash -l

彼らはあなたの~/.bash_profile環境変数を拾うべきです


4
この回答はより多くの賛成票を獲得し、単に選択された回答になるはずです。非常にシンプルでエレガントで、システム全体を飛び越える必要のある無数のクラッジを回避します。
JakeGould 2018

私はこの答え+1が好きです。rootのcrontabを実行するときにこれを使用できますか?/home/root私のシステムにはフォルダーがないため、これがrootのcrontab でどのように機能するのかわかりません。アイデア?
Seamus

スクリプト自体。その後、通常はcronで実行します。
breizhmg

@ジムはこの例を参照してください、古典的な実行可能ファイル(chmod 777)の使用#!/bin/bash。ここでの魔法は追加することです-l
ピータークラウス

22

@carestadの例を拡張すると、cronを使用してスクリプトを実行し、スクリプトに環境を含めることができます。

crontab -eファイルで:

SHELL=/bin/bash

*/1 * * * * $HOME/cron_job.sh

cron_job.shファイル:

#!/bin/bash
source $HOME/.bash_profile
some_other_cmd

.bash_profileのソースの後のコマンドは、ログインした場合と同じように環境を設定します。


16

私にとっては、phpアプリケーションの環境変数を設定する必要がありました。次のコードを私のcrontabに追加して、私はそれをさらに気に入っています。

$ sudo  crontab -e

crontab:

ENVIRONMENT_VAR=production

* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php

そしてdoSomethingWonderful.phpの中で私は環境の値を得ることができました:

<?php     
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"

これが役に立てば幸いです!


これは私にはうまくいきませんでした。環境変数は、crontab内で呼び出されたスクリプトでは使用できませんでした。
Nikhil

12

設定しcrontabた内容は、直接、およびスクリプト内の変数を使用して、cronjobsで使用できます。

cronjobの定義でそれらを使用します

crontabcronjobが使用できる変数を設定するように構成できます。

$ crontab -l
myvar="hi man"
* * * * * echo "$myvar. date is $(date)" >> /tmp/hello

これで、ファイル/tmp/helloは次のようになります。

$ cat /tmp/hello 
hi man. date is Thu May 12 12:10:01 CEST 2016
hi man. date is Thu May 12 12:11:01 CEST 2016

cronjobによって実行されるスクリプトで使用する

crontabスクリプトが使用できる変数を設定するように構成できます。

$ crontab -l
myvar="hi man"
* * * * * /bin/bash /tmp/myscript.sh

そして、スクリプト/tmp/myscript.shは次のようになります:

echo "Now is $(date). myvar=$myvar" >> /tmp/myoutput.res

以下/tmp/myoutput.resを示すファイルを生成します。

$ cat /tmp/myoutput.res
Now is Thu May 12 12:07:01 CEST 2016. myvar=hi man
Now is Thu May 12 12:08:01 CEST 2016. myvar=hi man
...

7

@Robert Brisitaを展開すると、が展開されます。また、スクリプトでプロファイルのすべての変数を設定したくない場合は、スクリプトの上部でエクスポートする変数を選択できます。

crontab -eファイルで:

SHELL=/bin/bash

*/1 * * * * /Path/to/script/script.sh

script.sh

#!/bin/bash
export JAVA_HOME=/path/to/jdk

some-other-command

7

の代わりに

0  *  *  *  *  sh /my/script.sh

bash -l -cを使用します

0  *  *  *  *  bash -l -c 'sh /my/script.sh'

1
理由だけではなく、ファイルの先頭にバッシュ宣言を持つのではなく、これを持っている-l。このように:#!/bin/bash -lこの他の答えはシンプルでエレガントです。
JakeGould 2018

1
bashではなくperl / python / ruby​​スクリプトを実行する必要がある場合はどうなりますか?Pythonスクリプトの先頭に#!/ bin / bash -lを追加できません。
イリヤカーラモフ2018

「bashではなくperl / python / ruby​​スクリプトを実行する必要がある場合はどうなりますか?」けっこうだ。しかし、私の心では、Pythonスクリプトを呼び出す単純なBashスクリプトラッパーを記述できます。PHPスクリプトについても同様です。その理由は、Bashではプロセスロックがはるかに優れており、信頼性が高いためですが、Bashスクリプトは依然として頭痛の種です。だから私はPHPで複雑なものを書いて、残りをBashに任せました。
JakeGould 2018

3

私はOh-my-zshMacbookで使用しているので、crontabタスクを実行するために多くのことを試しましたが、最後に、私の解決策は、.zshrc実行するコマンドの前にを追加することでした。

*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js

このタスクは30分ごとに実行され、 .zshrcに実行され、プロファイルをしてノードコマンドを実行します。

変数の前にドットを使用することを忘れないでください$HOME


2

この回答に触発されて変数を「注入」する別の方法は、次のとおりです(fcronの例)。

%daily 00 12 \
    set -a; \
    . /path/to/file/containing/vars; \
    set +a; \
    /path/to/script/using/vars

からhelp set

-aエクスポート用に変更または作成された変数をマークします。

-ではなく+を使用すると、これらのフラグがオフになります。

間のすべてだから、set -set +にエクスポートされるenvと、他のスクリプトのために利用可能である、など使用せずにset変数を調達ますが、ライブでsetだけ。

それ以外に、プログラムの実行に非rootアカウントが必要なときに変数を渡すことも役立ちますが、他のユーザーの環境内にいくつかの変数が必要になります。以下は、nullmailer varsを渡して電子メールヘッダーをフォーマットする例です。

su -s /bin/bash -c "set -a; \
                    . /path/to/nullmailer-vars; \
                    set +a; \
                    /usr/sbin/logcheck" logcheck

2

私は提供されたソリューションのほとんどを試しましたが、最初は何も機能しませんでした。しかし、うまくいかなかったのはソリューションではなかったことが判明しました。どうやら、私の~/.bashrcファイルは次のコードブロックで始まります。

case $- in
    *i*) ;;
    *) return;;
esac

これは基本的case statementに、現在のシェルの現在のオプションセットをチェックして、シェルがインタラクティブに実行されていることを確認するものです。シェルがインタラクティブに実行されている場合は、~/.bashrcファイルの調達に移ります。ただし、によって呼び出されたシェルではcron$-変数にはi対話性を示す値が含まれていません。したがって、~/.bashrcファイルが完全に取得されることはありません。その結果、環境変数が設定されることはありません。これが問題である場合は、次のようにコードブロックをコメントアウトして、再試行してください。

# case $- in
#     *i*) ;;
#     *) return;;
# esac

これが役に立つことを願っています


0

次のenvように環境変数を挿入するために、コマンドの先頭に追加することもできます。

0 * * * *   env VARIABLE=VALUE /usr/bin/mycommand
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.