はじめに
ユーザ環境変数を参照するプログラムを作りcrontabで実行しようとしたところ、環境変数が未定義でエラーとなってしまいました...。crontabでジョブを実行する場合は、ユーザの環境変数が反映されないようです。これは結構盲点で困りました...
何とか解決できたので、本記事で「crontabを使う際にもユーザ環境変数を反映する方法」をご紹介します。
動作確認OSは Ubuntu 22.04 のみですが、少なくともDebian系のディストリビューションであれば本記事の内容が使えると思います。
crontabでユーザ環境変数が反映されない現象の確認
まずはユーザ名 user
で定義されている環境変数を確認してみます。
$ env
SHELL=/bin/bash
HOSTNAME=0996dae4f85d
PWD=/home/user
LOGNAME=user
HOME=/home/user
LS_COLORS=rs=0:di=01;34:ln=01;...(出力省略)
TERM=xterm
USER=user
SHLVL=2
PATH=/usr/local/sbin:/usr/local/bin:..(出力省略)
MAIL=/var/mail/user
_=/usr/bin/env
OLDPWD=/
全部で12個の環境変数があります。
$ env | wc -l
12
次にcrontabでも同様にenv
を実行してファイル出力して確認してみましょう。
crontab -e
で以下の1行を追加します。
* * * * * env > /home/user/env_crontab.txt
最大1分待って出力結果を見てみます。
$ cat ~/env_crontab.txt
HOME=/home/user
LOGNAME=user
PATH=/usr/bin:/bin
SHELL=/bin/sh
PWD=/home/user
あれ? 環境変数は12個あるはずなのに、crontab経由で実行した場合は5個しか環境変数がありません。 これはどうしたものか...
解決策
次の手順で解決できました。
- (1) ユーザ環境変数をexportするスクリプトを作成する
- (2) 作成したスクリプトをcrontabの主ジョブを実行する前に
source
コマンドで反映する
以下に具体的に説明します。
(1) ユーザ環境変数をexportするスクリプトを作成する
まずはユーザ環境変数を読み込むためのスクリプトを作成します
env | grep -v LS_COLOR | awk '{ print "export " $0 }' \
> /path/to/export-env
念のため確認すると、export
コマンドで環境変数を設定するスクリプトができています。
$ cat /path/to/export-env
export SHELL=/bin/bash
export HOSTNAME=0996dae4f85d
...(出力省略)
export MAIL=/var/mail/user
export _=/usr/bin/env
スクリプトが動くかを以下のコマンドで確認し、何も表示されなければOKです。
source /path/to/export-env
/path/to/export-env
を作る際にgrep -v
でLS_COLOR
の環境変数出力を除外しているのは、今回試した環境だとLS_COLOR
の値に「;」が含まれていて、source /path/to/export-env
コマンドを実行するとエラーになるためです。このエラーはLS_COLOR
の値をダブルクオートで囲むと無くなりますが、「LS_COLOR
は使わない」前提でgrep -v
で回避しています。
(2) 作成したスクリプトをcrontabの主ジョブを実行する前にsource
コマンドで反映する
crontab -e
で次の2行を追加します。
SHELL=/bin/bash
* * * * * source /path/to/export-env && env > /home/user/env_crontab.txt
- 1行目 :
SHELL=/bin/bash
- crontabのデフォルトはshで実行されてsourceコマンドが使えないため、bashを使うように変更します
- 2行目
- メインのコマンドを実行する前に
source /path/to/export-env
を追加します
- メインのコマンドを実行する前に
結果確認
最大1分待って出力結果を見ると、ユーザ環境変数と(LS_COLOR
以外は)おおよそ同じになっていることを確認できます。
$ cat /home/user/env_crontab.txt
SHELL=/bin/bash
HOSTNAME=0996dae4f85d
PWD=/
LOGNAME=user
HOME=/home/user
TERM=xterm
USER=user
SHLVL=0
PATH=/usr/local/sbin:/usr/local/bin:..(出力省略)
MAIL=/var/mail/user
OLDPWD=/
_=/usr/bin/env
[参考] /etc/environment に追加する方法
実は上のようのことをしなくても/etc/environment
に次のコマンドでユーザ環境変数を追加すると簡単に解決します。
env | sudo tee -a /etc/environment > /dev/null
ところがこのやり方だと全ユーザにuser
(今回の場合)の環境変数が設定されてしまうため、あまりおすすめできないです。(特に複数ユーザで環境を使っている場合はこの方法は避けた方がいいです)
参考情報