Raspberry Piでアプリを作成するためにライブラリを探してみたところ、Python製のものが結構ありました。
そのため、慣れているVisual Studio + Python Tools for Visual Studio(以下、PTVS) でPythonを書いてみようと考えました。
codeplexには
PTVS supports CPython, IronPython, editing, browsing, Intellisense, mixed Python/C++ debugging, remote linux/MacOS debugging, profiling, IPython, Django, and cloud computing with client libraries for Windows, Linux and MacOS.
と、Linuxへのリモートデバッグに対応しているとの記載がありました。
そこで、Raspberry Pi上のPythonのリモートデバッグができるかを試してみました。
環境
Windowsまわり
- Windows7
- Visual Studio 2013 Community
- PTVS 2.1.0
- Python 2.7.10
- pip 7.0.1
- Git for Windows
- TeraTerm Portable 4.8.7
- SSH接続に使用
Raspberry Pi まわり
流れ
Windowsまわりのセットアップ
PTVSのダウンロード・インストール
以下よりダウンロード・インストールします。
Python Tools for Visual Studio - Downloads
Pythonのダウンロード・インストール
2.7系の最新である、Windows x86 MSI installer
をダウンロード・インストールします。
Python Releases for Windows | Python.org
環境変数の設定
Python2.7.9よりpipがScript
フォルダの下で同梱されるようになったため、以下の2つのパスを環境変数Path
に追加します。
- C:\Python27
- C:\Python27\Scripts
Installation — pip 7.0.3 documentation
Raspberry Piまわりのセットアップ
pipのインストール
デフォルトではpipが入っていないため、インストールします。
Raspberry Pi Documentation
pi@raspberrypi ~ $ sudo apt-get install python-pip
ptvsdのインストール
Raspberry Pi上でリモートデバッグするには、ptvsd
が必要になります。
また、stackoverflowの回答より、Raspberry Pi上のptvsd・WindowsのPTVSでバージョンを合わせた方が良さそうでした。
Unable to debug on Raspberry Pi using python tools for visual studio - Stack Overflow
そこで、バージョンを指定してpipでインストールします(指定しないと、現時点での最新版2.2.0b1が入ってしまいます)。
pi@raspberrypi ~ $ sudo pip install ptvsd==2.1.0 Downloading/unpacking ptvsd==2.1.0 Downloading ptvsd-2.1.0.zip (45Kb): 45Kb downloaded Running setup.py egg_info for package ptvsd Installing collected packages: ptvsd Running setup.py install for ptvsd Successfully installed ptvsd Cleaning up...
インストール結果を確認します。なお、Raspbianのpipのバージョンは1.1のため、pip freeze
で表示します。
pi@raspberrypi ~ $ pip freeze ... ptvsd==2.1.0 ...
PTVSでPythonスクリプトの作成
新しいプロジェクト > インストール済 > テンプレート > 他の言語 > Python
より、PythonApplication
を選択し、Pythonスクリプトを作成します。
サンプルとして、platform.system()
の結果を表示するコードを書きます。
# -*- coding: utf-8 -*- import ptvsd import platform ptvsd.enable_attach(secret = 'thinkAmi') os = platform.system() print u'ここでアタッチを待ちます' if os != 'Windows': ptvsd.wait_for_attach() print u'platform.systemの結果は %s です' % os
上記のうち、リモートデバッグに関する部分は以下の通りです。
ptvsdを使ってリモートデバッグする部分
ptvsdをimportして、アタッチできるようにします。
import ptvsd ptvsd.enable_attach(secret = 'thinkAmi')
リモートデバッグでアタッチされるのを待つ部分
リモートデバッグでアタッチをされるのを待つように指定しないとそのままデバッグが終了してしまうため、忘れないように記述します。
なお、開発端末のWindowsで試した時は発生しないよう、platform.system()の結果がWindows以外の場合(=Raspberry Pi上)のみ、待つようにしています。
if os != 'Windows': ptvsd.wait_for_attach()
Pythonスクリプトの文字コードの変更
Raspberry Pi上で実行するためにPythonスクリプトを転送する必要がありますが、その前にPythonスクリプトの文字コードを変更します。
というのも、PTVS 2.1.0で作成したPythonスクリプトの文字コードはShift_JIS
となっているため、そのまま転送すると日本語が以下のように文字化けするためです。
print u'platform.system?????? %s ???' % os
そのため、[保存オプションの詳細設定] ダイアログ ボックスを使用して、Pytyonスクリプトの文字コードをUTF-8のBOMなしへと変更します。
[保存オプションの詳細設定] ダイアログ ボックス
なお、ダイアログは名前をつけて保存する際に選択するか、以下の方法でメニュー追加します。
「保存オプションの詳細設定ダイアログ」では、以下の内容を入力します。
項目 | 値 |
---|---|
エンコード | Unicode (UTF-8 シグネチャなし) - コードページ 65001 |
行の終わり | 現在の設定 |
改行コード(行の終わり)は現在の設定
(おそらく、CR LF
) のままでも、Raspberry Pi上で動作しました。
なお、メニューに追加した場合、保存オプションの詳細設定ダイアログでOKボタンを押しただけでは保存されないため、忘れないようにCtrl + S
などで保存します。
Pythonスクリプトの転送
Raspberry Pi上にファイルを転送する方法はいくつかあるようですが、今回はGit for Windowsに入っているscp.exe
を使います。
Raspberry pi への配置方法 - sample-by-jsakamoto/SignalR-on-RaspberryPi
Raspberry Piでの作業
転送先ディレクトリを作成します。
pi@raspberrypi ~ $ mkdir remote_debug pi@raspberrypi ~ $ ls python_games remote_debug
Windowsでの作業
コマンドプロンプトなどでscpを使ってPythonスクリプトを転送します。今回は何も考えず、プロジェクト内のファイルをすべて転送します。
# Windows上のファイルを確認 ..\RemoteDebugPi>ls ptvs_raspberrypi.py PTVSRemoteDebug.pyproj # scpを使ってファイルを転送 ..\PTVSRemoteDebug>scp -r * pi@192.168.0.101:~/remote_debug #..\PTVSRemoteDebug>scp -r * pi@192.168.0.101:home/pi/remote_debug #=> これも可 pi@192.168.0.101's password: ptvs_raspberrypi.py 100% 282 0.2KB/s 00:00 PTVSRemoteDebug.pyproj 100% 1933 1.9KB/s 00:00
rsyncとSCPについて調べてみた - Pandora Pocket
リモートデバッグの実行
Raspberry Pi上でのPythonスクリプトの実行
転送したPythonスクリプトを実行すると、ptvsd.wait_for_attach()
が書かれている手前で停止し、TeraTermは以下のような表示となります。
# Pythonスクリプトのディレクトリへと移動 pi@raspberrypi ~ $ cd remote_debug # Pythonスクリプトを実行 pi@raspberrypi ~/remote_debug $ python ptvs_raspberrypi.py これからアタッチを待ちます
VisualStudioでブレークポイントを設定
今回は変数osの中身を知るため、最終行(このあたり)にブレークポイントを設定します。
なお、ブレークポイントを置かないままプロセスにアタッチすると、Raspberry Pi 上のPythonスクリプトは停止せずに終了してしまいます。
Visual Studioでプロセスにアタッチ
ツール > プロセスにアタッチ
を選択します。
「プロセスにアタッチ」ダイアログが開きますので、以下のように入力します。なお、修飾子の書式は <secret>@<Raspberry PiのIPアドレス/ホスト名>
で、<secret>
にはenable_attach()メソッドの引数secret
の値が入ります。
項目 | 値 |
---|---|
トランスポート | Python remote debugging |
修飾子 | thinkAmi@192.168.0.101 |
修飾子の欄でEnterキーを押すと、修飾子の部分がtcp://thinkAmi@192.168.0.101/
のように自動補完されるとともに、選択可能なプロセスにRaspberry Pi上のPythonのプロセスが表示されます。
続いて、該当のプロセスを選択して、「アタッチ」ボタンを押します。
すると、ブレークポイントで停止し、VisualStudio上で変数の中身などを確認することができます。
ブレークポイントを通過すると、TeraTermでは以下の実行結果が表示されます。
pi@raspberrypi ~/remote_debug $ python ptvs_raspberrypi.py ここでアタッチを待ちます platform.systemの結果は Linux です
その他
enable_attachメソッドにNoneを渡した場合
「プロセスにアタッチ」ダイアログにある「修飾子」欄に、<RaspberryPiのIPアドレス/ホスト名>
と入力すれば、自動補完されてアタッチできます。
Raspberry Pi の開いているポートについて
RaspberryPi上でptvsdが使用するポートがブロックされている場合、リモートデバッグできません。
そこで、RaspberryPiのデフォルトのブロック状況を見てみたところ、
pi@raspberrypi ~ $ sudo iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
となっており、特に制限はされていないようでした。
Raspberry Pi と iptables - Raspberry Pi を何年か使い続けるブログ
また、RaspberryPi上でptvsdを使ったPythonスクリプトを動作させている時に、別のTeraTermを立ち上げてポートの状態を確認してみましたが、
pi@raspberrypi ~ $ netstat -lnt Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:5678 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
ptvsdのデフォルトポート5678でLISTENしていました。
ソースコード
作成したプロジェクトをGitHubに上げておきました。
thinkAmi-sandbox/PTVS-remote_debug-sample
参考
PTVSまわり
- Cross Platform Remote Debugging · Microsoft/PTVS Wiki
- Part 5: Get started with Python: Debugging in PTVS - Canadian Developer Connection - Site Home - MSDN Blogs
- BuontempoConsulting: Remote debugging python in Visual Studio
ファイル転送まわり
今回はscpを使いましたが、rsyncについても調べたメモを残しておきます。