cronでは環境変数が設定されない

cronでは環境変数が最小限しか設定されないので、実行スクリプトかcronで環境変数が設定されるようにしなければいけない。

環境変数を設定する対象として、個別のcronジョブなのか、cron全体なのかを考える必要がある。

個別のcronジョブに環境変数を設定する

環境変数を設定する対象として、個別のcronジョブの場合を考える。

この場合は3つの方法が考えられる。

  1. ログインシェルとして実行する
  2. 環境変数をexportしているシェルスクリプトをsourceで読み込む
  3. コマンドの冒頭に環境変数を設定する

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