概要
USB ケーブル 1 本で Raspberry Pi Zero と接続できる様になったので、Python プログラムを Raspberry Pi Zero で動かしてみます。 しかし、今後の試行錯誤を考え、(自分にとっての)プログラムを作りやすい環境を整えてみました。 具体的には以下を行なっています。
- ssh でのログインをパスワードなしにする
- Python 2.x 系と 3.x 系を切り替えられる様にする
- Mac でプログラムを作成し、Raspberry Pi Zero では実行のみ行う様にする
確認環境
- Raspberry Pi Zero
- RASPBIAN JESSIE LITE 2016-11-25
- MacBook Pro 2016 Late
- macOS 10.12
参考情報
- Raspberry Pi ZeroをUSBケーブル1本で遊ぶ | Japanese Raspberry Pi Users Group
- Raspberry Pi Zero からインターネットに接続する方法
- signals - Ctrl-C handling in SSH session - Unix & Linux Stack Exchange
- ssh で接続した時に Ctrl-C をリモートに渡す方法
- 引数を処理する | UNIX & Linux コマンド・シェルスクリプト リファレンス
- bash でコマンド引数を扱う方法
- シェル変数のデフォルト値を設定する、未初期化時にエラーメッセージを出力してスクリプトを強制終了する - 百日半狂乱
- シェル変数にデフォルト値を設定する方法
- virtualenvでpython環境を管理する - Qiita
- virtualenv の使い方
前回の記事
解説
ssh コマンドでパスワードを入力せずにログインする
前回、ssh コマンドでログインできる様になった。 しかし、ssh コマンドでログインする度にパスワードを入力するのは面倒だ。 そこで、公開鍵認証を使用してパスワード入力せずにログインできる様にする。
Mac で鍵ペアを生成して、公開鍵のみを Raspberry Pi の ~/.ssh/authorized_keys に登録する。 秘密鍵は絶対に外部に漏らしてはいけない。 ssh-keygen コマンドは鍵ペアを生成する。 鍵ペアは ~/.ssh ディレクトリに id_rsa (秘密鍵), id_rsa.pub (公開鍵) として生成される。 安全のためにパスフレーズ (passphrase) は入力した方が良い。 id_rsa.pub を Raspberry Pi の ~/.ssh/authorized_keys に登録する。
mac:~ nosix$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/Users/nosix/.ssh/id_rsa): Created directory '/Users/nosix/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /Users/nosix/.ssh/id_rsa. Your public key has been saved in /Users/nosix/.ssh/id_rsa.pub. ...省略... mac:~ nosix$ scp ~/.ssh/id_rsa.pub pi@raspberrypi.local:~ id_rsa.pub 100% 404 0.4KB/s 00:00 mac:~ nosix$ ssh pi@raspberrypi.local ...省略... pi@raspberrypi:~ $ mkdir .ssh pi@raspberrypi:~ $ cat id_rsa.pub >> .ssh/authorized_keys pi@raspberrypi:~ $ rm id_rsa.pub pi@raspberrypi:~ $ exit
authorized_keys は存在していないため cat コマンドではなく mv コマンドでも構わないが、
既に authorized_keys が存在する場合には追記する必要がある。
cat src_file >> dst_file
で追記できることを知っておくと便利かと思う。
以上で設定は完了したので、ssh コマンドでログインしてみる。 途中で接続を続けるかと尋ねられるので yes とする。 Raspberry Pi を識別するための情報(ECDSA key fingerpring)が Mac の ~/.ssh/known_hosts に登録される。 次回からは途中で尋ねられることなくログインできる。
mac:~ nosix$ ssh pi@raspberrypi.local The authenticity of host 'raspberrypi.local (<省略>)' can't be established. ECDSA key fingerprint is SHA256:<省略>. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'raspberrypi.local,<省略>' (ECDSA) to the list of known hosts. The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Fri Dec 16 04:36:43 2016 from <省略> pi@raspberrypi:~ $
ログインできれば成功。 Raspberry Pi (の authorized_keys) に登録した Mac からはパスワードなしでログインできる。 Mac 側では ssh-keygen で入力したパスフレーズを 1 度だけ入力することがある。 パスフレーズで認証しておくことで、ssh でログインする際にはパスワードが不要になる。 パスワードは passwd コマンドで複雑なパスワードに変更する。
~/.bash_profile にコマンドのエイリアス(別名)を登録しておくと便利。 以下の 1 行を追加すると pish コマンドで Raspberry Pi に ssh でログインできる。
alias pish='ssh pi@raspberrypi.local'
PC に再ログインした場合には、ssh-add コマンドを実行して認証する。 認証が完了していない場合には、ssh の実行の際にパスフレーズの入力が求められる。
mac:~ nosix$ pish Enter passphrase for key '/Users/nosix/.ssh/id_rsa':
Python3 環境を Raspberry Pi に作る
Python には 2.x 系と 3.x 系が存在する。 2.x 系と 3.x 系で異なる部分があり、2.x 系で動くからと言って 3.x 系では動かないという場合がある。 もちろん、反対もあり得る。 Raspberry Pi に標準でインストールされている Python は 2.x 系。 3.x 系の Python も導入し、2.x 系と 3.x 系を切り替えられる様にしておく。
Raspberry Pi に python3, pip (Python のパッケージ管理ツール), virtualenv (実行環境を切り替えるツール) をインストールする。 pip を使うことで、多くの人が作ってくれた Python の便利道具(パッケージ)を簡単に導入できる。 パッケージにはバージョンがあり、バージョンの組み合わせによっては動作しないこともある。 様々な実験を行うために個別の実験室(仮想環境; virtualenv)を用意しておくと便利。(実験室は比喩。) パッケージを導入する際には実験室を指定して導入し、他の実験室には影響が及ばない様にする。 また、実験室毎に Python2 と Python3 のいずれを使うかを決めておくことができる。
まず、Raspberry Pi からインターネットに接続できる様にする。 Mac でインターネット共有を設定する。 RNDIS/Ethernet Gadget にチェックを入れる。
次に、python3, python3-rpi.gpio, pip, virtualenv をインストールする。
pi@raspberrypi:~ $ sudo apt-get install python3 ...省略... pi@raspberrypi:~ $ sudo apt-get install python3-rpi.gpio ...省略... pi@raspberrypi:~ $ sudo apt-get install python-pip ...省略... pi@raspberrypi:~ $ sudo pip install virtualenv ...省略...
実験室 (仮想環境; virtualenv) を作成する。 例では、~/pyenv/python2, ~/pyenv/python3 を作成している。 apt-get で install した python3-rpi.gpio を使用するために、--system-site-packages を指定している。 (ディレクトリはお好みで。)
pi@raspberrypi:~ $ mkdir ~/pyenv pi@raspberrypi:~ $ virtualenv -p python2 ~/pyenv/python2 Running virtualenv with interpreter /usr/bin/python2 New python executable in /home/pi/pyenv/python2/bin/python2 Also creating executable in /home/pi/pyenv/python2/bin/python Installing setuptools, pip, wheel...done. pi@raspberrypi:~ $ virtualenv --system-site-packages -p python3 ~/pyenv/python3 Running virtualenv with interpreter /usr/bin/python3 Using base prefix '/usr' New python executable in /home/pi/pyenv/python3/bin/python3 Also creating executable in /home/pi/pyenv/python3/bin/python Installing setuptools, pip, wheel...done.
試しに実験室に入る。activate を source コマンドで読み込むと仮想環境が有効になる。
pi@raspberrypi:~ $ source ~/pyenv/python3/bin/activate (python3) pi@raspberrypi:~ $ (python3) pi@raspberrypi:~ $ python --version Python 3.4.2
実験室から出る(仮想環境を無効にする)には、deactivate コマンドを使う。
(python3) pi@raspberrypi:~ $ deactivate pi@raspberrypi:~ $
以降、pip でパッケージをインストールする際には、実験室に入ってから行う。 全ての実験室で共通して使いたいパッケージの場合には、実験室に入らずに pip でインストールする。
Mac 環境でソースコードを作成して、Raspberry Pi で動かす
Raspberry Pi で IDLE を使用してソースコードを編集しても良いが、Mac 環境の方がツールも多く便利である。 Mac 環境でソースコードを作成して、Raspberry Pi にコピーして Raspberry Pi で実行する仕組みを用意する。 (この節の内容は試行中のものです。)
~/bin/pidep コマンドを自作する。(dep は Deploy の意。) Mac から Raspberry Pi にファイルを scp でコピーして、Mac から ssh で実行するスクリプトになっている。
コマンドを実行できる様にする。
mac:~ nosix$ chmod +x ~/bin/pidep
Raspberry Pi に ~/pyhome ディレクトリと仮想環境 ~/pyenv/python3 を用意しておく。
pi@raspberrypi:~ $ mkdir ~/pyhome
pidep の PI_HOME と PI_ENV で指定している。 PI_HOME はコピー先のルート、PI_ENV は実行時に使用する仮想環境の指定。
使い方
まずは、Python3 プログラム(hello.py)を用意する。1 秒毎に Hello と表示される。
from time import sleep while True: print("Hello") sleep(1)
このプログラムを pidep で Raspberry Pi にコピーして実行する。 -s はコピー元、-r は実行するプログラム(スクリプト)を指定する。
mac:tmp nosix$ pidep -s hello.py -r hello.py hello.py 100% 68 0.1KB/s 00:00 Hello Hello Hello Hello ^CTraceback (most recent call last): File "hello.py", line 5, in <module> sleep(1) KeyboardInterrupt Connection to raspberrypi.local closed.
-d でコピー先を指定できる。 -r を省略するとコピーのみ、-s を省略すると実行のみ行われる。
mac:tmp nosix$ pidep -s hello.py -d loop.py -r loop.py mac:tmp nosix$ pidep -r hello.py mac:tmp nosix$ pidep -s hello.py