Raspberry Pi 2にて、direnvを使ってPythonの環境を構築する

Raspberry Pi 2上のPython環境について調べてみたところ、direnvを使って構築するのが良さそうだったので、試してみた時のメモを残します。

 

環境

Windows

 

Raspberry Pi
  • Raspberry Pi 2 Model B
  • Raspbian 2015-02-16
  • Python 3.2.3 (デフォルト)
  • direnv 2.6.0
  • pip 1.1
  • virtualenv 13.0.3

 

direnvのセットアップ

ダウンロード

direnvのreleaseページではソースコードやバイナリが配布されています。
Releases · zimbatm/direnv

一方、Debianにもパッケージがあったものの、若干バージョンが古いようでした。
Debian -- Details of package direnv in sid

 
direnvの2.5.0にてPythonまわりのアップデートがあったことから、今回は公式のバイナリをダウンロードして使うことにしました。

バイナリはいくつか種類がありますが、RaspberryPi上で実行するため、direnv.linux-arm版のバイナリをダウンロードします。

pi@raspberrypi ~ $ curl -L https://github.com/zimbatm/direnv/releases/download/v2.6.0/direnv.linux-arm -o direnv
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   399    0   399    0     0    434      0 --:--:-- --:--:-- --:--:--   592
100 2864k  100 2864k    0     0   438k      0  0:00:06  0:00:06 --:--:--  622k

なお、バイナリの配布先のURLがAWSにリダイレクトされていたので、以下を参考にcurlを使いました。

 

インストール
pi@raspberrypi ~ $ sudo install direnv /usr/local/bin

 

piユーザのログインシェルを確認

direnvでは使用しているシェルにより設定が変わるため、piユーザのログインシェルを確認すると、Bashのようでした。

pi@raspberrypi ~ $ echo $SHELL
/bin/bash

現在使用されているシェルが知りたい - ITmedia エンタープライズ

 

.bashrcの設定

GitHubのREADMEを参考に、.bashrcの設定を行います。

まずは.bashrcがあることを確認します。

pi@raspberrypi ~ $ ls -a
.  ..  .bash_history  .bash_logout  .bashrc  direnv  .profile  python_games

Linuxコマンド集 - 【 ls 】 ファイルやディレクトリの情報を表示する:ITpro

 
続いて、.bashrcに追記します。

pi@raspberrypi ~ $ echo 'eval "$(direnv hook bash)"' >> ~/.bashrc

 

direnvを試す

以下を参考にdirenvを試してみます。
direnvを使おう - Qiita

 

direnv edit . でエラー

ディレクトリを作成してdirenv edit .を実行したところ、エラーが出ました。

# direnv用ディレクトリの作成
pi@raspberrypi ~ $ mkdir direnv-test
pi@raspberrypi ~ $ cd direnv-test/

# direnv用ディレクトリの中で実行したところ、エラー
pi@raspberrypi ~/direnv-test $ direnv edit .
direnv: $EDITOR not found.
open: invalid option -- 't'
Usage: open [OPTIONS] -- command

This utility help you to start a program on a new virtual terminal (VT).

Options:
  -c, --console=NUM   use the given VT number;
  -f, --force         force opening a VT without checking;
  -l, --login         make the command a login shell;
  -u, --user          figure out the owner of the current VT;
  -s, --switch        switch to the new VT;
  -w, --wait          wait for command to complete;
  -v, --verbose       print a message for each action;
  -V, --version       print program version and exit;
  -h, --help          output a brief help message.

direnv: error exit status 1

 
エラーに従い環境変数を追加してみましたが、結果は同じでした。

# 環境変数の設定
pi@raspberrypi ~/direnv-test $ export EDITOR=$EDITOR:/usr/bin/nano

# 環境変数の確認
pi@raspberrypi ~/direnv-test $ echo $EDITOR
:/usr/bin/nano

# direnv editを再実行してもエラー
pi@raspberrypi ~/direnv-test $ direnv edit .
/bin/sh: 1: :/usr/bin/nano: not found
direnv: error exit status 127

 

direnv edit .を使わないでdirenvを実行

エラーが出ているdirenv edit .を使わずに、自分で.envrcファイルを作成し、direnvを実行してみます。

# .envrcファイルの作成
pi@raspberrypi ~/direnv-test $ nano .envrc
direnv: loading .envrc
direnv: export ~PATH

# .envrcファイルの中身を確認
pi@raspberrypi ~/direnv-test $ cat .envrc
PATH_add bin

 
実行結果を確認します。

# .envrcがあるディレクトリの中で環境変数を確認
pi@raspberrypi ~/direnv-test $ echo $PATH
/home/pi/direnv-test/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games

# 外に出て環境変数を確認
pi@raspberrypi ~/direnv-test $ cd ..
direnv: unloading
pi@raspberrypi ~ $ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games

.envrcファイルのあるディレクトリの中にいる時のみ/home/pi/direnv-test/binが追加されていることから、direnvは正常に動作しているようでした。

 
ちなみに、.envrcファイルの書き方については、以下の公式ページにまとまっていました。
direnv/direnv-stdlib.1.md at master · zimbatm/direnv

 

Pythonの環境を構築

デフォルトの状態でdirenvを実行した場合、エラー

今回はPythonの3系でセットアップします。

Python3のvirtualenv環境を作るため、.envrcには、layout python3の一行のみを記述して実行します。

# ファイルを作る
# direnv allowの実行を求められる
pi@raspberrypi ~/direnv-test $ nano .envrc
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.

# ファイルの中身を見る
pi@raspberrypi ~/direnv-test $ cat .envrc
layout python3

# direnv allowするとエラー
pi@raspberrypi ~/direnv-test $ direnv allow
direnv: loading .envrc
/bin/bash: line 297: virtualenv: command not found
direnv: export +VIRTUAL_ENV ~PATH

 
デフォルトのPython3にはvirtualenvがないため、エラーになったようです。

 

pipとvirtualenvのインストール

以前、Windowsにvirtualenvをdistribute経由でインストールしたことがあります。 Windows7 x64でvirtualenvを使えるようにする - メモ的な思考的な

しかし、現在はpipからインストールできるので、まずはPython3版のpip(python3-pip)をインストールします。
Installing Python packages - Raspberry Pi Documentation

# 一応update
pi@raspberrypi ~/direnv-test $ sudo apt-get update
...
Reading package lists... Done

# Python3版を入れる
pi@raspberrypi ~/direnv-test $ sudo apt-get install python3-pip
...
Setting up python3-pip (1.1-3) ...

 
続いて、virtualenvを入れます。Python3版のため、pip-3.2というコマンドを使ってインストールします。

いくつかwarningが出ますが、無事にインストール出来ました。

pi@raspberrypi ~/direnv-test $ sudo pip-3.2 install virtualenv
...
Successfully installed virtualenv
Cleaning up...

 

再度direnv allowを実行

実行後しばらく待ちますが、無事に終わります。

# direnv allowの実行
pi@raspberrypi ~/direnv-test $ direnv allow
direnv: loading .envrc
Running virtualenv with interpreter /usr/bin/python3
New python executable in /home/pi/direnv-test/.direnv/python-3.2.3/bin/python3
Also creating executable in /home/pi/direnv-test/.direnv/python-3.2.3/bin/python
Installing setuptools, pip, wheel...direnv: ([direnv export bash]) is taking a while to execute. Use CTRL-C to give up.
done.
direnv: export +VIRTUAL_ENV ~PATH

 

direnvで使われるvirtualenvの動作確認

通常、virtualenvをactivateで有効化し、deactivateで無効化しますが、direnvでは必要なのかどうかを試してみます。

現時点での、direnv用ディレクトリ内で使用しているパッケージ一覧は以下の通りです。

pi@raspberrypi ~/direnv-test $ pip freeze
wheel==0.24.0

 

direnv用ディレクトリ内のpipコマンドのPythonバージョンについて

direnv用ディレクトリ内ではpipコマンドでパッケージをインストールします。

ただ、RaspberryPi上のpipコマンドはPython2を指していたことから、念のためpipがPython2/3のどちらで動作しているかを確認します。

Python2しか動作しないnfcpyをpipで入れてみました。

pi@raspberrypi ~/direnv-test $ pip install nfcpy
Collecting nfcpy
  Could not find a version that satisfies the requirement nfcpy (from versions: )
No matching distribution found for nfcpy

 
エラーとなったことから、direnv用ディレクトリ内のpipはPython3で動作しているようです。

 

ライブラリのインストール先の確認

次に適当な何かのパッケージを入れてみます(今回はpyjokes)。ちなみに、direnvディレクトリ内でもsudoを付けて実行するとグローバルへとインストールされてしまいました。

# pyjokesのインストール
pi@raspberrypi ~/direnv-test $ pip install pyjokes
...
Successfully installed pyjokes-0.1.2

# インストール結果の確認
pi@raspberrypi ~/direnv-test $ pip freeze
pyjokes==0.1.2
wheel==0.24.0

 
direnvのディレクトリから出て、pipの状態を確認します。

# ディレクトリから出る
pi@raspberrypi ~/direnv-test $ cd ../
direnv: unloading

# pipによるパッケージの確認
pi@raspberrypi ~ $ pip-3.2 freeze
RPi.GPIO==0.5.11
## FIXME: could not find svn URL in dependency_links for this package:
distribute==0.6.24dev-r0
numpy==1.6.2
picamera==1.9
pifacecommon==4.1.2
pifacedigitalio==3.0.4
pygame==1.9.2a0
pyserial==2.5
virtualenv==13.0.3
wsgiref==0.1.2
Warning: cannot find svn location for distribute==0.6.24dev-r0

 
このことから、activate/deactivateなしでも、direnv用ディレクトリ内はvirtualenv環境として動作しているということが分かりました。

 

activateやdeactivateの利用について

明示的にactivatedeactivateを利用も可能です。$PATHにdirenv下のPythonにパスが通っているため、コマンドは短くて済みます。

pi@raspberrypi ~ $ cd direnv-test/
direnv: loading .envrc
direnv: export +VIRTUAL_ENV ~PATH

# activateの実行
pi@raspberrypi ~/direnv-test $ source activate

# virtualenvっぽく、先頭に環境名が付加された
(python-3.2.3)pi@raspberrypi ~/direnv-test $


# deactivateの実行
(python-3.2.3)pi@raspberrypi ~/direnv-test $ deactivate

# virtualenvの環境名が無くなった
pi@raspberrypi ~/direnv-test $

 
以上で、Raspberry Pi2 にてdirenvを使ってPythonの環境を構築することができました。