cronでは環境変数が設定されない
cronでは環境変数が最小限しか設定されないので、実行スクリプトかcronで環境変数が設定されるようにしなければいけない。
環境変数を設定する対象として、個別のcronジョブなのか、cron全体なのかを考える必要がある。
個別のcronジョブに環境変数を設定する
環境変数を設定する対象として、個別のcronジョブの場合を考える。
この場合は3つの方法が考えられる。
- ログインシェルとして実行する
- 環境変数を
export
しているシェルスクリプトをsource
で読み込む - コマンドの冒頭に環境変数を設定する
1と2は実行スクリプトとcronそれぞれに設定ができるが、3はcronに設定するのみである。
1. ログインシェルとして実行する
実行スクリプトに記載
個別のcronジョブがスクリプトを実行する形式であれば、スクリプトのshebangで、ログインシェルとして動くように#!/bin/bash -l
とすればいい。
cronに記載
実行スクリプトの有無にかかわらず設定したいのであれば、cronでbash -l -c 'コマンド'
とすればいい。-l
でログインシェルとして動くようになる。
例
00 00 * * * postgres bash -l -c 'psql -p 5432 dbname -c "VACUUM ANALYZE"'
2. 環境変数をexport
しているシェルスクリプトをsource
で読み込む
実行スクリプトに記載
実行スクリプトの冒頭でsource
を実行する。
例
source /home/username/.bash_profile
cronに記載
実行スクリプトの有無にかかわらず設定したいのであれば、cronでsource
を書いてから;
の前後にスペースを入れずに目的のコマンドを記載する。
例
00 00 * * * postgres source ~/.bash_profile;psql -p 5432 dbname -c "VACUUM ANALYZE"
3. コマンドの冒頭に環境変数を設定する
cronに記載
変数名=値 コマンド
とコマンドの冒頭に書くと、そのコマンドに対してだけ有効な環境変数を設定できる。
$ a=test env | grep a=
a=test
$ echo $a
$ a=test sh -c 'echo $a'
test
$ echo $a
これはcronでも同様に記載できるため、以下のように書くことができる。
00 00 * * * postgres PATH="/usr/local/bin:$PATH" psql -p 5432 dbname -c "VACUUM ANALYZE"
スクリプトを作らず直接cronにコマンドを書くことを考慮すると、cronで対応するように統一するのがいいかもしれない。
cron全体にわたる環境変数を設定する
cron全体にわたる環境変数を設定したい場合は、crontabの先頭で変数名=値
と書けばいい。
ただし、crontabの先頭は各ジョブのコマンドを書く部分とは異なり、シェルスクリプトとして解釈されないため、PATH="/usr/local/bin:$PATH"
の$PATH
部分のような変数を書くことができない。
SAMPLE_FLAG=true
* * * * * echo $SAMPLE_FLAG > /tmp/sample.txt