• このエントリーをはてなブックマークに追加

はじめに

ここ2日ほど,シャワーとトイレ以外,ほとんど椅子に座って生活しているissmです.

perlbrewなPerlをcronから使う際に,ちょっとハマりかけたのでメモ.よく考えればわかったことなんですけどね.

とりあえずcronしてみる

私の環境では,perl-5.12.2 が入っています.

% perlbrew list
* perl-5.12.2
  perl-5.8.8
  perl-5.8.9
  /usr/bin/perl (5.10.0)

で,何らかの非コアモジュールが利用できるとします.(ここでは Log::Minimal

% perl -MLog::Minimal -e 'infof "hogehoge"'
2011-01-22T12:28:27 [INFO] hogehoge at -e line 1

これを cron で実行してみるとします.

% crontab -e
* * * * *  /usr/bin/env perl -MLog::Minimal -e 'infof "hogehoge"' > $HOME/cron.log 2>&1

さて実行結果は?

% cat ~/cron.log
Can't locate Log/Minimal.pm in @INC (@INC contains: /Library/Perl/Updates/5.10.0 /System/Library/Perl/5.10.0/darwin-thread-multi-2level /System/Library/Perl/5.10.0 /Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0 /Network/Library/Perl/5.10.0/darwin-thread-multi-2level /Network/Library/Perl/5.10.0 /Network/Library/Perl /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level /System/Library/Perl/Extras/5.10.0 .).
BEGIN failed--compilation aborted.

はい,エラーでした.@INC が,5.10.0 のものを指してますね.

cron実行時の環境を確認する

cron 実行時の Perl のバージョンは?

crontab -e で次のように書き換えてみます.

* * * * *  perl -V >> $HOME/cron.log 2>&1

で,1分ほどしてログをのぞいてみます.

% cat ~/cron.log
Summary of my perl5 (revision 5 version 10 subversion 0) configuration:
 
...
 
  @INC:
    /Library/Perl/Updates/5.10.0
    /System/Library/Perl/5.10.0/darwin-thread-multi-2level
    /System/Library/Perl/5.10.0
    /Library/Perl/5.10.0/darwin-thread-multi-2level
    /Library/Perl/5.10.0
    /Network/Library/Perl/5.10.0/darwin-thread-multi-2level
    /Network/Library/Perl/5.10.0
    /Network/Library/Perl
    /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level
    /System/Library/Perl/Extras/5.10.0
    .

5.10.0,つまりデフォルトのものですね.

環境変数は?

同じく crontab -e

* * * * *  /usr/bin/env > $HOME/cron.log 2>&1

同じくログをチェック.

% cat ~/cron.log
SHELL=/bin/sh
USER=issm
PATH=/usr/bin:/bin
PWD=/Users/issm
SHLVL=1
HOME=/Users/issm
LOGNAME=issm
_=/usr/bin/env

すごいピュアです.

ちなみにシェル(zsh)上では,perlbrewの環境変数がいくつか設定されていますね.

% env | grep -i perlbrew
PAfTH=/Users/issm/perl5/perlbrew/bin:/Users/issm/perl5/perlbrew/perls/perl-5.12.2/bin:/usr/local/bin:/usr/local/sbin:/Users/issm/local/bin:/Users/issm/local/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/local/sbin:/Users/issm/local/bin:/Users/issm/local/sbin
PERLBREW_PERL=perl-5.12.2
PERLBREW_VERSION=0.15
PERLBREW_PATH=/Users/issm/perl5/perlbrew/bin:/Users/issm/perl5/perlbrew/perls/perl-5.12.2/bin
PERLBREW_ROOT=/Users/issm/perl5/perlbrew
PATH_WITHOUT_PERLBREW=/usr/local/bin:/usr/local/sbin:/Users/issm/local/bin:/Users/issm/local/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/local/sbin:/Users/issm/local/bin:/Users/issm/local/sbin

というわけで,5.12.2 な Perl へのパスを通してやればよさげです.

環境変数を追加してみる

5.12.2 な Perl を実行できるように,環境変数 $PATH を追加した上で cron を実行してみます.

% crontab -e
PERLBREW_PERL="perl-5.12.2"
 
* * * * *  PATH="$HOME/perl5/perlbrew/perls/$PERLBREW_PERL/bin:$PATH" /usr/bin/env perl -MLog::Minimal -e 'infof "hogehoge"' > $HOME/cron.log 2>&1

実行結果は?

% cat ~/cron.log
2011-01-22T13:20:00 [INFO] hogehoge at -e line 1

念のためバージョン確認も.

% crontab -e
PERLBREW_PERL="perl-5.12.2"
 
* * * * *  /usr/bin/env PATH="$HOME/perl5/perlbrew/perls/$PERLBREW_PERL/bin:$PATH" perl -V > $HOME/cron.log 2>&1

一応,ひと手間でバージョンを切り替えられるようにしてみたり.

% cat ~/cron.log
Summary of my perl5 (revision 5 version 12 subversion 2) configuration:
 
...
 
  %ENV:
    PERLBREW_PERL="perl-5.12.2"
  @INC:
    /Users/issm/perl5/perlbrew/perls/perl-5.12.2/lib/site_perl/5.12.2/darwin-2level
    /Users/issm/perl5/perlbrew/perls/perl-5.12.2/lib/site_perl/5.12.2
    /Users/issm/perl5/perlbrew/perls/perl-5.12.2/lib/5.12.2/darwin-2level
    /Users/issm/perl5/perlbrew/perls/perl-5.12.2/lib/5.12.2
    .

大丈夫っぽいですね.

まとめ

perlbrew に限らず,ユーザのローカル環境等に入れたツール等を cron から使う場合,環境変数 $PATH に追記したり,対象の実行ファイルをフルパスで指定したりするのが無難っぽいですね.

おわりに

ホントちょっと考えればすぐにわかることでしたが,気づくまでの確認プロセスを含めて,つらつらと書いてみました.