Python で GUI を扱う
どうも,筆者です. 前回に引き続き,Python で GUI を利用する方法についてまとめていく. 前回は,Python Script を exe 形式に変換する方法をまとめたが,その時に利用したスクリプトでは,画面を作成していなかった.
今回は,ボタンやテキストを配置し,より GUI よりのものを作成する.
workspacememory.hatenablog.com
雛形の作成
今回も,Python で GUI プログラムを作成する際に tkinter を利用する.tkinter を用いた場合の雛形となるものを以下に示す.
import tkinter as tk class AppClass(tk.Frame): def __init__(self, master=None): super().__init__(master) self.pack() self.createWidgets() def createWidgets(self): # ここに部品を配置する def main(): root = tk.Tk() root.title('title') # タイトルの設定 root.resizable(0, 0) # ウィンドウのリサイズ禁止 # インスタンスの生成 app = AppClass(master=root) # ループ処理 app.mainloop()
これに,肉付けを行い,画面を作成する.今回は,「ラベルの配置」,「テキストボックスの配置」,「ボタンの配置」を取り扱う.
ラベルの生成
HTML でいう「label」を配置する.tkinter では,以下のようにする.
self.label = tk.Label(self, text='sample')
テキストボックスの生成
HTML でいう一行テキストボックス「input type=text」を配置する.tkinter では,以下のようにする.
self.varEntry = tk.StringVar() self.entry = tk.Entry(self, textvariable=self.varEntry)
追加したテキストボックスには,テキストボックスに値を設定したり,テキストボックスから値を取り出すことができる.そのやり取りをするための変数を用意する必要がある. 「self.varEntry」がデータの受け渡しに利用する変数である.値の設定・値の取得はそれぞれ以下のようにする.
# 値の設定 self.varEntry.set('hoge') # 値の取得 data = self.varEntry.get()
ボタンの生成
HTML でいう「button」を配置する.tkinter では,以下のようにする.
self.button = tk.Button(self, text='button')
また,ボタンには押下時に関数を実行するよう,設定ができる.サンプルを以下に示す.
self.button = tk.Button(self, text='button', command=self.sampleFunc) def sampleFunc(self): print('call funciton')
ただ,この記述では関数に引数を渡すことができない.引数を渡して実行するには,以下のようにする.
self.button = tk.Button(self, text='button', command=self.sampleFunc(1)) def sampleFunc(self, val): def innerFunc(): print(val) return innerFunc
これでうまく処理できる理由は,以下のサイトにまとまっている.
各要素の配置
定義はできたが,このままでは,各要素をどのように配置するか設定されていない状態となる.各要素の配置は,以下のようにする.
# ラベル,テキストボックス,ボタンという順に配置する self.label.grid(column=0, row=0) self.entry.grid(column=1. row=0) self.button.grid(column=2. row=0)
大雑把だが,今回使用する機能の紹介を終える.他にも様々な引数をとるが,完全に把握し切れていないため,分からない部分は都度調べることにする.
Python Script を実行形式(exe 形式)に変換
どうも,筆者です. 今回は,Python Script を Windows で動作する exe 形式に変換する手順を説明する.
動作環境
利用した OS,Python のバージョンを以下に示す.
pyinstaller のインストール
Python Script を exe 形式に変換するため,pyinstaller をインストールする.コマンドプロンプトに以下のコマンドを入力する.
python -m pip install pyinstaller
以下のコマンドを入力し,バージョンを確認しておく.筆者の環境では,3.3.1 となった.
pyinstaller -v
exe 形式に変換
今回は,以下のような Python Script を exe 形式に変換する.この Python Script は,動作確認用に作成したものである.ここでは,test.py という名前で保存した.
#!/usr/bin/env python # -*- coding: shift-jis -*- import tkinter from tkinter import filedialog as dialog from tkinter import messagebox as msgbox import os, sys # ディレクトリ名とファイル名に分割 def splitFilePath(fileName): dirName = os.path.dirname(fileName) baseName = os.path.basename(fileName) return dirName, baseName # ファイルダイアログを開き、対象のファイルのパスを取得 def getTargetFileName(): # 現在のディレクトリを取得 currentDir = os.getcwd() # ダイアログを開き、フルパスを取得 fileName = dialog.askopenfilename(title="Choose file", initialdir=currentDir) if fileName is None or fileName == '': baseName = '' else: # ファイル名のみ抽出 _, baseName = splitFilePath(fileName) return baseName # ファイルの存在確認と拡張子の確認 def chkFilePath(filePath): # 以下の 2 点を確認 # 1.指定されたパスのファイルが存在するか # 2.対象とする拡張子か targetExtensionList = ['txt', 'csv'] # 対象とする拡張子のリスト if filePath == '': return False # ファイルの存在確認 if not os.path.exists(filePath): # 存在しない場合 outMsg = '以下のファイルが存在しません\n%s' % filePath msgbox.showinfo('Error', outMsg) return False else: # 拡張子の確認 _, ext = os.path.splitext(filePath) if ext[1:] not in targetExtensionList: joinExt = ', '.join(map(lambda x: '.%s' % x, targetExtensionList)) outMsg = '対象の拡張子ではありません: %s\n対象の拡張子: %s' % (ext, joinExt) msgbox.showinfo('Error', outMsg) return False else: return True def execution(inputFilePath): dirName, baseName = splitFilePath(inputFilePath) outputFilePath = os.path.join(dirName, 'out_' + baseName) with open(outputFilePath, 'w') as fout: for line in open(inputFilePath, 'r'): data = line.replace('\n', '') fout.write(data + '\n') def main(): argv = sys.argv argc = len(argv) useFilePath = '' # GUI の初期設定 rootTk = tkinter.Tk() rootTk.withdraw() if argc < 2: useFilePath = getTargetFileName() else: useFilePath = argv[1] if chkFilePath(useFilePath): # 処理を実行 useFullPath = os.path.abspath(useFilePath) execution(useFullPath) if __name__ == '__main__': main()
Python Script を exe 形式に変換するには,コマンドプロンプトに以下のコマンドを入力する.
rem icon をつけない場合 pyinstaller --onefile --clean --noconsole test.py rem icon をつける場合 rem 同一フォルダに test.ico を配置しておく必要がある. pyinstaller --onefile --clean --noconsole --add-binary test.ico;. --icon=test.ico test.py
実行すると,以下のようなログが表示される.最後に successfully が表示されていれば変換完了である.なお,exe ファイルは dist フォルダ以下に生成される.
62 INFO: PyInstaller: 3.3.1 62 INFO: Python: 3.6.4 62 INFO: Platform: Windows-7-6.1.7601-SP1 62 INFO: wrote path\test.spec 62 INFO: UPX is not available. 62 INFO: Removing temporary files and cleaning cache in userPath\AppData\Roaming\pyinstaller 93 INFO: Extending PYTHONPATH with paths ['path\\test', 'path\\test'] 93 INFO: checking Analysis 93 INFO: Building Analysis because out00-Analysis.toc is non existent 93 INFO: Initializing module dependency graph... 93 INFO: Initializing module graph hooks... 109 INFO: Analyzing base_library.zip ... 2683 INFO: running Analysis out00-Analysis.toc 2683 INFO: Adding Microsoft.Windows.Common-Controls to dependent assemblies of final executable required by userPath\AppData\Local\Programs\Python\Python36\python.exe 3229 INFO: Caching module hooks... 3229 INFO: Analyzing path\test.py 3369 INFO: Loading module hooks... 3369 INFO: Loading module hook "hook-encodings.py"... 3447 INFO: Loading module hook "hook-pydoc.py"... 3447 INFO: Loading module hook "hook-xml.py"... 3634 INFO: Loading module hook "hook-_tkinter.py"... 3759 INFO: checking Tree 3759 INFO: Building Tree because out00-Tree.toc is non existent 3759 INFO: Building Tree out00-Tree.toc 3822 INFO: checking Tree 3822 INFO: Building Tree because out01-Tree.toc is non existent 3822 INFO: Building Tree out01-Tree.toc 3853 INFO: Looking for ctypes DLLs 3853 INFO: Analyzing run-time hooks ... 3853 INFO: Including run-time hook 'pyi_rth__tkinter.py' 3853 INFO: Looking for dynamic libraries 4024 INFO: Looking for eggs 4024 INFO: Using Python library userPath\AppData\Local\Programs\Python\Python36\python36.dll 4024 INFO: Found binding redirects: [] 4024 INFO: Warnings written to path\build\test\warntest.txt 4056 INFO: Graph cross-reference written to path\build\test\xref-test.html 4087 INFO: checking PYZ 4087 INFO: Building PYZ because out00-PYZ.toc is non existent 4087 INFO: Building PYZ (ZlibArchive) path\build\test\out00-PYZ.pyz 4508 INFO: Building PYZ (ZlibArchive) path\build\test\out00-PYZ.pyz completed successfully. 4508 INFO: checking PKG 4508 INFO: Building PKG because out00-PKG.toc is non existent 4508 INFO: Building PKG (CArchive) out00-PKG.pkg 4804 INFO: Updating manifest in userPath\AppData\Roaming\pyinstaller\bincache00_py36_64bit\python36.dll 4804 INFO: Updating resource type 24 name 2 language 1033 5413 INFO: Updating manifest in userPath\AppData\Roaming\pyinstaller\bincache00_py36_64bit\_ssl.pyd 5413 INFO: Updating resource type 24 name 2 language 1033 5569 INFO: Updating manifest in userPath\AppData\Roaming\pyinstaller\bincache00_py36_64bit\unicodedata.pyd 5569 INFO: Updating resource type 24 name 2 language 1033 5584 INFO: Updating manifest in userPath\AppData\Roaming\pyinstaller\bincache00_py36_64bit\pyexpat.pyd 5584 INFO: Updating resource type 24 name 2 language 1033 5616 INFO: Updating manifest in userPath\AppData\Roaming\pyinstaller\bincache00_py36_64bit\_hashlib.pyd 5616 INFO: Updating resource type 24 name 2 language 1033 5662 INFO: Updating manifest in userPath\AppData\Roaming\pyinstaller\bincache00_py36_64bit\_bz2.pyd 5662 INFO: Updating resource type 24 name 2 language 1033 5678 INFO: Updating manifest in userPath\AppData\Roaming\pyinstaller\bincache00_py36_64bit\_lzma.pyd 5678 INFO: Updating resource type 24 name 2 language 1033 5694 INFO: Updating manifest in userPath\AppData\Roaming\pyinstaller\bincache00_py36_64bit\_socket.pyd 5694 INFO: Updating resource type 24 name 2 language 1033 6037 INFO: Updating manifest in userPath\AppData\Roaming\pyinstaller\bincache00_py36_64bit\select.pyd 6037 INFO: Updating resource type 24 name 2 language 1033 6084 INFO: Updating manifest in userPath\AppData\Roaming\pyinstaller\bincache00_py36_64bit\_tkinter.pyd 6084 INFO: Updating resource type 24 name 2 language 1033 6130 INFO: Updating manifest in userPath\AppData\Roaming\pyinstaller\bincache00_py36_64bit\tk86t.dll 6130 INFO: Updating resource type 24 name 1 language 1033 8814 INFO: Building PKG (CArchive) out00-PKG.pkg completed successfully. 8829 INFO: Bootloader userPath\AppData\Local\Programs\Python\Python36\lib\site-packages\PyInstaller\bootloader\Windows-64bit\runw.exe 8829 INFO: checking EXE 8829 INFO: Building EXE because out00-EXE.toc is non existent 8829 INFO: Building EXE from out00-EXE.toc 8845 INFO: SRCPATH [('test.ico', None)] 8845 INFO: Updating icons from ['test.ico'] to userPath\AppData\Local\Temp\tmp1k39lqf2 8845 INFO: Writing RT_GROUP_ICON 0 resource with 20 bytes 8845 INFO: Writing RT_ICON 1 resource with 68578 bytes 8860 INFO: Appending archive to EXE path\dist\test.exe 8892 INFO: Building EXE from out00-EXE.toc completed successfully.
Power Shell で Excel を操作する(Excel 起動,ファイルオープン,保存,ファイルクローズ)
どうも,筆者です.
たまには,無駄なプログラム(スクリプト)を作成してみようと思う.今回は,「対象とする Excel ファイルを Power Shell から起動し,その後保存して閉じる」というものを作成する.
今回は,以下のような手順で処理する.
Excel アプリケーションの起動
Power Shell で Excel アプリケーションを起動するには,以下のようにする.
$excel = New-Object -ComObject Excel.Application $excel.Visible = $false # 画面上に表示させない $excel.DisplayAlerts = $true # 警告メッセージは表示する
Excel ファイルを開く
続いて,Excel ファイルを開くには,以下のようにする.
# 現在のディレクトリの絶対パスを取得 $currentPath = (Convert-Path .) # 対象の Excel ファイル名 $filename = "sample.xlsx" $book = $excel.Workbooks.Open($currentPath + "/" + $filename)
Excel ファイルを保存し閉じる
# 上書き保存 $book.Save() # ブックを閉じる $excel.Workbooks.Close()
Excel アプリケーションを終了する
Excel アプリケーションを終了するには,以下のようにする.
$excel.Quit()
後処理
Excel アプリケーションを終了しただけでは,プロセスが残っている.これは,今回の Power Shell で利用した変数を OS が保持しているためである.
このため,変数を破棄する必要がある.ここでは,$book と $excel を変数として利用したため,以下のようにして破棄する.
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($book) [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
対象とする Excel ファイルのリストの取得
ある程度自動化したいため,対象とする Excel ファイルをリストにし,テキスト形式で保存する.このテキストファイルを読み込み順に処理する方法を考える.
例として,以下のようなテキストファイルを利用する.これを list.txt として保存する.
sample01.xlsx dummy sample02.xlsx dummy sample03.xlsx dummy sample04.xlsx dummy sample05.xlsx dummy sample06.xlsx dummy sample07.xlsx dummy sample08.xlsx dummy sample09.xlsx dummy sample10.xlsx dummy
list.txt を Power Shell で読み込むには,以下のようにする.
$excelFileList = @(Get-Content -Path ($currentPath + "/list.txt") | %{$_.split(" ")[0]})
「Get-Content」コマンド(Linux の cat コマンド)でファイルの中身を出力する.出力データを 1 行ずつ読み込み,スペースで区切り,最初のデータを配列の要素として取り出す. ここで,「%」は foreach のエイリアスである.また「$_」には,読み込んだ 1 行のデータが格納されている.
作成したスクリプト
作成したスクリプトを以下に示す.
try { # 現在のディレクトリの絶対パスを取得 $currentPath = (Convert-Path .) # Excelオブジェクト作成 $excel = New-Object -ComObject Excel.Application $excel.Visible = $false # 画面上に表示させない $excel.DisplayAlerts = $true # 警告メッセージは表示する # 対象ファイルの1列目を取り出す $excelFileList = @(Get-Content -Path ($currentPath + "/list.txt") | %{$_.split(" ")[0]}) foreach($filename in $excelFileList) { # ファイル名の出力 Write-Host $filename # 対象とするExcelファイル $book = $excel.Workbooks.Open($currentPath + "/" + $filename) # 上書き保存 $book.Save() # ブックを閉じる $excel.Workbooks.Close() # 300ms待つ Start-Sleep -m 300 } # Excelを閉じる $excel.Quit() } finally { # 変数の破棄 [System.Runtime.Interopservices.Marshal]::ReleaseComObject($book) [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) }
追記1(2018/03/04)
Power Shell を起動する際に,実行権限を変更する必要があるため,以下のような bat ファイルを作成した.
@echo off echo execute Power Shell powershell -ExecutionPolicy RemoteSigned -file openClose_Excel.ps1
この bat ファイルを動かす場合は,引数を処理して,作業ディレクトリを指定する処理を加える必要がある.Power Shell で引数を取得する方法を以下に示す.
# 現在のディレクトリで初期化 Param ( $argv1 = "." ) # 引数を必須にする場合は,以下のようにする. #Param ( [parameter(mandatory = $true)]$argv1 = "." ) try { # 現在のディレクトリの絶対パスを取得 $currentPath = (Convert-Path $argv1) # 処理が続く ... }
SoftEther を利用した VPN サーバの構築
どうも,筆者です.今回は,前回セットアップした Raspberry Pi 3 Model B を利用して,VPN サーバを立てた.何度か試してみた結果,ようやくうまくいったので,ここに記録しておく.
VPN に関しては以下のサイトを参考にした.
システムのアップデート
まずは,おなじみのシステムのアップデートを行う.
sudo apt-get update sudo apt-get upgrade sudo apt-get dist-upgrade
初期設定
システムのアップデートが完了したら,初期設定を行っていく.まずは,swap 領域を無効にするため,以下のコマンドを入力する.
sudo swapoff --all # swap off にする sudo apt-get remove dphys-swapfile # swap 機能を無効にする.
次に,必要なエディタのインストールとその設定を行う.
sudo apt-get install -y vim # vim をインストール sudo update-alternatives --config editor # sudo で使用するエディタの設定をする.ここでは vim を選択 sudo vim /etc/vim/vimrc # vim の設定ファイルを修正する sudo ln -s /etc/vim/vimrc /root/.vimrc # 設定ファイルを root の .vimrc に反映 ln -s /etc/vim/vimrc ~/.vimrc # 同様に自分のローカルにも反映する
vim の設定ファイルに関しては,以前記事にしたので,そちらを参照のこと.
workspacememory.hatenablog.com
最後に,pi ユーザの変更とパスワードなしでの root 切り替えを無効にする設定を行う.これは,以下のサイトを参考にした.
sudo useradd -M tmp # 一時的なユーザ tmp の作成 sudo gpasswd -a tmp sudo # sudo 権限を付与 sudo passwd tmp # パスワードの設定 exit # 一旦抜ける ### tmp ユーザでログインする ### sudo usermod -l admin pi # pi ユーザのユーザ名を admin に変更 sudo usermod -d /home/admin -m admin # pi ユーザのホームディレクトリ名を admin に変更 sudo groupmod -n admin pi # pi ユーザのグループを admin に変更 exit # ログアウト ### admin ユーザでログインする ### sudo userdel tmp # tmp ユーザを削除 sudo passwd admin # admin ユーザのパスワードを変更 sudo rm /etc/sudoers.d/010_pi-nopasswd # パスワードなしで root 権限を取得で気ないようにするため,指定のファイルを削除
これで,自分の中では,初期設定は完了である.早速,本題の VPN 環境を構築していく.
SoftEther を利用した VPN 環境の構築
ここでは,VPN サーバの環境構築を行う.構築手順は,以下のようになる.
- bridge アダプタを利用可能にするため,bridge-utils をインストールする.
- softether のデータを Web からダウンロードして,インストールする.
- vpnserver をサービスへ登録し,自動起動する.
- Windows 側で VPN Server の設定を行う.
- ネットワーク環境の設定を行う.ここか一番ハマッた部分である.
- ルータ側でアドレス変換の設定を行い,外部から VPN サーバにアクセスできるようにする.
この順に処理を進める.
bridge-utils のインストール
vim のインストールと同様に,インストールするだけである.
sudo apt-get install -y bridge-utils
SoftEther のインストール
以下のサイトから,SoftEther をダウンロードしてくる.
それぞれ,選択肢を以下のように設定する.
- ダウンロードするソフトウェアを選択
- コンポーネントを選択
- プラットフォームを選択
- CPU を選択
- ARM EABI (32bit)
すべて選択すると,ダウンロード可能なファイルの一覧が表示される.今回は,
SoftEther VPN Server (Ver 4.24, Build 9651, beta) softether-vpnserver-v4.24-9651-beta-2017.10.23-linux-arm_eabi-32bit.tar.gz (5.40 MB)
をダウンロードした.wget コマンドを用いて,tar.gz ファイルをダウンロードする.
wget http://jp.softether-download.com/files/softether/v4.24-9651-beta-2017.10.23-tree/Linux/SoftEther_VPN_Server/32bit_-_ARM_EABI/softether-vpnserver-v4.24-9651-beta-2017.10.23-linux-arm_eabi-32bit.tar.gz
展開し,インストールを行う.
tar zxvf softether-vpnserver-v4.24-9651-beta-2017.10.23-linux-arm_eabi-32bit.tar.gz pushd vpnserver/ echo -e "1\n1\n1\n" | make popd sudo mv vpnserver/ /usr/local/ pushd /usr/local/vpnserver/ sudo chmod 600 * sudo chmod 700 vpncmd vpnserver popd
これでインストールは完了である.
サービスへの登録・自動起動の設定
次に,vpnserver をサービスに登録する.好みのエディタで「/etc/systemd/system/vpnserver.service」を新規に開く.そして,以下を記述し,保存する.
sudo vim /etc/systemd/system/vpnserver.service ### 以下を /etc/systemd/system/vpnserver.service に記述し保存する ### [Unit] Description=SoftEther VPN Server After=network.target network-online.target [Service] ExecStart=/usr/local/vpnserver/vpnserver start ExecStop=/usr/local/vpnserver/vpnserver stop Type=forking RestartSec=3s [Install] WantedBy=multi-user.target
その後,以下のコマンドでサービスを有効にし,自動起動の設定もする.
sudo systemctl daemon-reload sudo systemctl enable vpnserver.service sudo systemctl start vpnserver.service
Windows 側での設定
再び,以下のサイトから Windows 用のマネージャファイルをダウンロードし,インストールする.CPU が AMD の場合はよく分からない. SoftEther ダウンロード センター
それぞれ,選択肢を以下のように設定する.
- ダウンロードするソフトウェアを選択
- コンポーネントを選択
- プラットフォームを選択
- CPU を選択
マネージャを開き,順に設定する.この辺りの設定は,以下のサイトに図付で説明があるので,そちらを参考にする.
- 新しい接続設定から,接続先を設定する.ここでは,DHCP で割り当てられた IP アドレス 192.168.33.31 を設定した.
- 管理者パスワードを設定する.
- リモートアクセス VPN サーバーを選択する.
- 仮想 HUB 名を決める.ここでは,vpn とした.
- DDNS 名を決める.重複しないようにする必要があるため,自分が使いたいものが既に設定されている場合,使えない.
- 「L2TP サーバ機能を有効にする」にチェックを入れる.IPsec 事前共有鍵も設定する.
- 「VPN Azure を有効にする」にチェックを入れる.
- ユーザーを作成する.ログイン時に使用する.
- ローカルブリッジの設定は,ここでは行わない.(ブリッジ接続する~のまま置いておく)
すべて設定すると,VPN サーバ管理画面が表示される.次に,以下の手順で,tap デバイスの設定を行う.
- VPN サーバの管理画面において,左下にある「ローカルブリッジ設定」を選択する.
- 「仮想 HUB」として,先ほど決めた「vpn」を選択する.
- 「新しい tap デバイスとのブリッジ接続」を選択する.
- 新しい tap デバイス名に任意の名前を入力する.ここでは,softether とした.
- 「ローカルブリッジを追加」を選択する.
これで,Windows 側の設定は完了である.
ネットワーク環境の設定
一番ハマッたネットワークの設定である.最近の Raspberry Pi では,「/etc/dhcpcd.conf」にネットワークインタフェースの設定を記述するらしいが,ここでは,「/etc/network/interfaces」に記述する. 固定 IP を振りたかったが,どうしてもうまくできなかったため,dhcp として処理した.「/etc/network/interfaces」に以下を記述する.
# interfaces(5) file used by ifup(8) and ifdown(8) # Please note that this file is written to be used with dhcpcd # For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf' # Include files from /etc/network/interfaces.d: source-directory /etc/network/interfaces.d # The loopback network interface auto lo iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet manual auto wlan0 iface wlan0 inet static address 192.168.33.8 netmask 255.255.255.0 gateway 192.168.33.1 wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf auto br0 iface br0 inet dhcp ### 固定 IP でも設定可能なはずであるが,うまく動作しなかったため,DHCP とした. ### # eth0 を tap_softether に割り当てる.この時,softether の部分は,先程の「tap デバイスの設定」で設定した名前にする. bridge_ports eth0 tap_softether bridge_maxwait 10
ここで,ちゃっかり,無線 LAN の設定をしている.「/etc/wpa_supplicant/wpa_supplicant.conf」の設定方法は,以下を参照のこと.
workspacememory.hatenablog.com
設定完了後,reboot をかける.問題がなければ,正常に起動するはずである.この時から,eth0 に割り当てられていた IP アドレスではログインできなくなっていた. そのため,予め設定しておいた無線 LAN 側の IP アドレスで,リモートアクセスする.また,マネージャツールも無線 LAN の IP アドレスを設定することで,管理画面に移行できる.
ssh -X admin@192.168.33.8
リモートログイン後,以下のコマンドで eth0 に tap デバイスが割り当てられているか確認する.
brctl show bridge name bridge id STP enabled interfaces br0 xyz.abcdefghijk012345 no eth0 tap_softether
ルータの設定
最後に,ルータの設定を行う.筆者は,「WHR-1166DHP3」を使用しているので,型番で調べて設定した.忘れそうなので,やり方を示しておく.ここでのソフトウェアのバージョンは,2.9 である. 「詳細設定」の画面に移動し,「セキュリティー」の「ポート変換」に移動する.以下のように IP アドレスとポートの対応付けを登録する.IP アドレスは,無線 LAN 側に割り当てたものを利用する.
- プロトコル TCPポート: 443, LAN 側の IP アドレス:192.168.33.8
- プロトコル TCPポート: 5555, LAN 側の IP アドレス:192.168.33.8
- プロトコル UDPポート: 500, LAN 側の IP アドレス:192.168.33.8
- プロトコル UDPポート: 4500, LAN 側の IP アドレス:192.168.33.8
以上で,すべての設定は完了である.疲れた.
Raspberry Pi 3 Model B のセットアップ
どうも,筆者です.
今回,Raspberry Pi を新たに購入した.イメージを落としてきて,microSD に焼くまでの作業はササっとできた.しかし,LAN ケーブルも HDMI ケーブルも見つからなかったため,無線 LAN による接続設定ができなかった. ここでは,microSD に設定ファイルを配置するという方法で,無線 LAN の設定を行うことを試みた.
イメージを microSD カードに焼くまで
ここは,苦労せずにできた.以下の環境下で,セットアップを行った.また,使用する OS イメージは,Raspbian Stretch Lite である.
OS: Ubuntu 14.04(仮想環境上)
# Step 1 sudo parted -l # このコマンドの結果により,microSD が /dev/sdb として認識されていることが分かった(/dev/sdb は環境により変わる). # Step 2 sudo umount /dev/sdb1 # アンマウントする # Step 3 sudo dd bs=1024K if=2017-09-07-raspbian-stretch-lite.img of=/dev/sdb # これでイメージを microSD に焼くことができる
もしくは,以下のサイトを参考に,「DD for Windows」というツールを用いて microSD にイメージを焼く.
http://techblog.clara.jp/2016/04/raspberry-pi-3-model-b_install_and_ssh_connect/
無線 LAN の設定
さて,ここからが本題である.といっても,調べたらたくさん出てきたので,ほとんど引用する形となる. 無線 LAN の設定は,「wpa_supplicant.conf」というファイルに保存される.
イメージを焼いた microSD 上にこの設定ファイルを配置しておけば,起動時に勝手に「/etc/wpa_supplicant/wpa_supplicant.conf」に上書きされる仕様になっているらしい. こちらのサイトを参考にして,設定ファイルを作成し,microSD 上に配置した.同時に,「ssh」というファイルも microSD 上に配置した.
ssh によるリモートログイン
最後に,ssh 接続するための IP アドレスを調査する.これだけは,調べてもいい方法が見つからなかったため,Ubuntu 側からネットワーク内のアドレスを調査する shell script を作成した.
#!/bin/bash networkAddr=192.168.33 seq 1 32 | while read ipAddr; do ping -c 1 -w 1 ${networkAddr}.${ipAddr} > /dev/null ret=$? if [ ${ret} -eq 0 ]; then macAddr=$(arp -a ${networkAddr}.${ipAddr} 2> /dev/null) echo ${networkAddr}.${ipAddr} ${macAddr^^} fi done
これを「ipAddr.sh」として保存し,実行すると,以下のようになる.
192.168.33.1 BUFFALO.SETUP (192.168.33.1) AT **:**:**:**:**:** [ETHER] ON ETH0 192.168.33.3 ? (192.168.33.3) AT **:**:**:**:**:** [ETHER] ON ETH0 192.168.33.12 ? (192.168.33.12) AT B8:27:EB:**:**:** [ETHER] ON ETH0 192.168.33.31 ? (192.168.33.31) AT B8:27:EB:**:**:** [ETHER] ON ETH0
Raspberry Pi 3 の MAC アドレスは B8:27:EB で始まるものであるので,12 か 31 となる.ここで,12 は以前設定した Raspberry Pi 3 であることが分かっているので,今回の接続先は 31 となる. 以上から,ターミナルを立ち上げて,
ssh pi@192.168.33.31
とコマンドを入力することで,Raspberry Pi に接続できる.
余談
他にも,MAC アドレスから IP アドレスを調べる方法として,以下のサイトが見つかった.ブロードキャストを使う方法は思いつかなかったので今度から使ってみようと思う.
Raspberry PiのIPアドレスをログインせずに調べるやり方|NEWS|株式会社INDETAIL(インディテール)