web-dev-qa-db-ja.com

ユーザー環境変数をcronjobに読み込む

ユーザーの環境変数を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
4
Sebastian Barth

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 foundexport: command not foundが表示されるはずです。エラー出力を調べることはトラブルシューティングのために本当に重要です。

もちろん、Ubuntuで標準の.bashrcを使用している場合、非インタラクティブスクリプトからソースを取得しようとすると、すぐに停止します。おそらく、必要な設定を別のファイルで非対話的に使用する方がよいでしょう(おそらく.profileはデフォルトでshによって読み取られます)?

4
tripleee

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を標準入力として評価しないようにするために必要です。

4
Andrew Domaszek

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;
0
Sebastian Barth