ユーザーの環境変数をcronjobに読み込むにはどうすればよいですか?
私のUbuntuマシンで毎分スクリプトを開始するcronjobがあります。
* * * * * /home/user/myscript.sh;
このスクリプトでは、$Java_HOME
や$M2_HOME
などの環境変数を使用して、ビルドプロセスを自動的に開始します。問題は、これらの変数が.bashrc
を介してexport Java_HOME=/../..
に設定されていることです。
したがって、スクリプトを実行する前に、これらのファイルをsource
します。
* * * * * source ~/.bash_profile; source ~/.bashrc; /home/user/myscript.sh;
ただし、変数は設定されていません。これをテストするには、echo
を介して環境変数をenv
ログファイルに出力します。
env >> ~/env.log
echo $M2_HOME >> ~/env.log
ログファイルにはまだ変数が含まれていません。以下のみがファイルに追加されます($M2_HOME
などは含まれません)。
LANGUAGE=en_US:en
HOME=/home/user
LOGNAME=user
PATH=/usr/bin:/bin
LANG=en_US.UTF-8
Shell=/bin/sh
PWD=/home/user
シェルでスクリプトを実行すると、すべての変数がenv.log
に出力されます。
source
コマンドをスクリプトファイルに追加した場合も同様です。変数の宣言の前にexport
キーワードを削除した場合のみ、echo $var
コマンドで表示されます。しかし、これらの宣言を管理していないため、これは解決策ではありません。
限られたsh Shell問題で@trippleeの解決策を試しましたが、それでも機能しません。さらに、問題を示すための2番目のスクリプトを含まない非常に単純なcronjobに削減しました。
* * * * * . $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log;
cat /home/user/env.log
:
LANGUAGE=en_US:en
HOME=/home/user
LOGNAME=user
PATH=/usr/bin:/bin
LANG=en_US.UTF-8
Shell=/bin/sh
PWD=/home/user
Cronジョブの構文はsh
のみに制限されているため、~
のようなバシズムを使用することはできません。幸い、修正は簡単です。$HOME
に置き換えるだけです。同様に、source
は.
(ドットのみ)に置き換える必要があります。
もちろん、sh
からスクリプトを使用する場合は、ソーススクリプトでBash構文を使用しないでください。おそらく最も簡単な修正は、これらのものをスクリプトに移行する(またはCronが実行するラッパースクリプトを作成する)ことです。
スクリプト内では、必要に応じてbash
を使用できます。もちろん、Shebang行が#!/bin/bash
ではなく#!/bin/sh
(必要に応じてパスを調整)であることが条件です。
何らかの理由でそれが気に入らない場合は、crontab
ファイルにBashを明示的に指定してインライン化できます。
* * * * * bash -c 'source ~/.bash_profile; source ~/.bashrc; ./myscript.sh'
問題が発生した場合、cron
から送信されたメールにsource: command not found
とexport: command not found
が表示されるはずです。エラー出力を調べることはトラブルシューティングのために本当に重要です。
もちろん、Ubuntuで標準の.bashrc
を使用している場合、非インタラクティブスクリプトからソースを取得しようとすると、すぐに停止します。おそらく、必要な設定を別のファイルで非対話的に使用する方がよいでしょう(おそらく.profile
はデフォルトでsh
によって読み取られます)?
Tripleeeの答えに追加するには、crontabでシェルを指定することにより、すべてのcronをbash(または選択したシェル)で評価させることができます。
Shell=/bin/bash
* * * * * . $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log;
編集そして、それが何をしているのかを本当に知りたい場合は、次のコマンドで十分に冗長にする必要があります。
/bin/bash -x -c '. $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log' > /tmp/cron.`date +\%s`
set -x
またはコマンドラインの-xフラグを指定すると、ほとんどのシェルは評価されたすべての行を出力します。
コマンドラインでテストするには、日付コマンドから\を削除します。これは、cronが%sを標準入力として評価しないようにするために必要です。
cronの完全なtty がありません。しかし、Sudo -i
から実行すると、1つ取得されます。
* * * * * Sudo -u user -i bash -c '. $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log;'
または、スクリプトを開始するには:
* * * * * Sudo -u user -i bash -c '. $HOME/.bash_profile; . $HOME/.bashrc; /home/user/myscript.sh;'
ターゲットスクリプトを開始するBashスクリプトにsource
コマンドを配置すると、きちんと整えられます。
* * * * * Sudo -u user -i /home/user/mystarter.sh;