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