cron実行時に環境変数を読み込む

2023-02-20

Crontabを実行時に環境変数が読み込まれない

cronに登録しているスクリプトでログに特定の文字を含むとメールするスクリプトがあります。メールする本文やタイトルに日本語文字が場合に文字化けが発生しました。
スクリプト単体だと問題なく日本語で表示されcron経由だと文字化けするので環境変数がおかしくなっているか調査しました。

簡単に環境変数を出力する下記のスクリプトを作りました。「printenv」コマンドでも良かったですが必要のない項目も表示されるので、下記のようなスクリプトしました

#!/bin/bash

echo "USER: $USER" > env_result.log
echo "PATH: $PATH" >> env_result.log
echo "LANG: $LANG" >> env_result.log
echo "HOME: $HOME" >> env_result.log

「testuser」というユーザーで上記のスクリプトを実行すると下記のように環境変数が読み込まれています

 $ cat env_result.log
USER: testuser
PATH: /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/testuser/.local/bin:/home/testuser/bin
LANG: ja_JP.UTF-8
HOME: /home/testuser

これをcronで登録して実行すると下記のようになります。PATHがほとんど最低限しか読み込まれてません、Cron経由だと.bash_profileに記載した環境変数が読み込まれていないようです

$ crontab -e
* * * * * /home/testuser/test_env.sh

$ cat env_result.log
USER: testuser
PATH: /usr/bin:/bin
LANG: ja_JP.UTF-8
HOME: /home/testuser

 

crontabを実行時に環境変数が読み込む方法

cron実行に実行しているユーザーの環境変数を読み込ませる方法がいくつかありますが、「bash」のオプションで読み込む方法を紹介します。

–login、-l のオプションでは、ログインシェルとして起動されたかのように bash を動作します。

bashの「Man page of BASH」だと下記のように説明されています

–login オプション付きの非対話的シェルとして起動されると、 /etc/profile ファイルが存在すれば、 bash はまずここからコマンドを読み込んで実行します。
このファイルを読んだ後、 bash は ~/.bash_profile, ~/.bash_login, ~/.profile をこの 順番で探します。
bash は、この中で最初に見つかり、かつ読み込みが可能であるファイルから コマンドを読み込んで実行します。

環境変数を出力するシェルスクリプトのbashコマンドに「-l」のオプションを追加して、「bash -l」として、下記のスクリプトに変更してからcronに登録しました

#!/bin/bash -l

echo "USER: $USER" > env_result.log
echo "PATH: $PATH" >> env_result.log
echo "LANG: $LANG" >> env_result.log
echo "HOME: $HOME" >> env_result.log

.bash_profile, .bash_login,などを読み込むように変更してからcronを実行すると以下ように環境変数が読み込まれるようになります

$ crontab -e
* * * * * /home/testuser/test_env.sh

$ cat env_result.log
USER: testuser
PATH: /usr/bin:/bin:/usr/local/sbin:/usr/sbin:/home/testuser/.local/bin:/home/testuser/bin
LANG: ja_JP.UTF-8
HOME: /home/testuser

crontab内でPATH定義する

シェルスクリプトでログインシェルとして扱うようにしてもいいですが、crontab内に直接 PATHを指定してもPATHが通るようになります

$ crontab -e

PATH=//usr/bin:/bin:/usr/local/sbin:/usr/sbin:/home/testuser/.local/bin:/home/testuser/bin

* * * * * /home/testuser/test_env.sh