ラピロの電源を入れる。パソコン側のSSHクライアント「putty」を使って、ラピロのラズパイにssh接続するのだが、時々、SSH接続出来ないことがある。なぜなら、我が家のネットワークはDHCPでIPアドレスが割り当てられるので、定期的にIPアドレスが変わるのです。毎回、arpコマンドで予想してとか、DHMIでディスプレイに繋ぎなおしてとか、DHCPで割り当てられたIPアドレスを調べるのが面倒なので、Raspberry Piが起動した時に、ラピロがIPアドレスを教えてくれるようにしてみる。
IPアドレスを調べるには[ip a]コマンドを使う。
$ ip a 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000 link/ether b8:27:eb:13:ae:e3 brd ff:ff:ff:ff:ff:ff 3: wlan0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether b8:27:eb:46:fb:b6 brd ff:ff:ff:ff:ff:ff inet 192.168.1.11/24 brd 192.168.1.255 scope global wlan0 valid_lft forever preferred_lft forever
"1:lo"は、ラズパイのループバックアドレスといい、自分自身のIPアドレス[127.0.0.1]。自分のラズパイで自分のプログラムにアクセスする時に使う。
"2:eth0"は、ラズパイの有線LANのIPアドレス。上記の場合はLANケーブルを接続していないので、"DOWN"になってIPアドレスも割り当てされていない。
"3:wlan0"が、Wifi無線LANを示し、"inet 192.168.1.11"の部分がDHCPで割り当てられたIPアドレス。このIPアドレスが定期的に変わる。
ラピロに教えて欲しいのは、無線LANのIPアドレスだけなので[ip a]コマンドが出力する情報を絞り込みたい。まずは、無線LANの[wlan0]だけ表示する。
pi@raspberrypi:~$ ip a show wlan0 3: wlan0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether b8:27:eb:46:fb:b6 brd ff:ff:ff:ff:ff:ff inet 192.168.1.11/24 brd 192.168.1.255 scope global wlan0 valid_lft forever preferred_lft forever inet6 2405:6580:c6e0:0:3d6c:6cd5:346b:bf07/64 scope global noprefixroute dynamic valid_lft 14359sec preferred_lft 12559sec inet6 fe80::3be0:3e99:b94e:d2c5/64 scope link valid_lft forever preferred_lft forever
IPv4のアドレスである[inet ]以外にも、IPv6のアドレス[inet6]も表示されるので、今度はIPv4[inet ]の行だけを表示する。
pi@raspberrypi:~$ ip a show wlan0 | grep "inet " inet 192.168.1.11/24 brd 192.168.1.255 scope global wlan0
最後にIPアドレス以外の情報をカットする。スペース' 'を区切りとして(先頭の連続するスペースも含め)6個目のフィールドを取り出す。
pi@raspberrypi:~$ ip a show wlan0 | grep "inet " | cut -f6 -d ' ' 192.168.1.11/24
IPアドレス[192.168.1.11/24]をラピロに全部喋らすのはうっとおしいので、不変の[192.168.1.]部分も省略することにした。欲しい情報は[11]のみ。
pi@raspberrypi:~$ ip a show wlan0 | grep "inet " | cut -f6 -d ' ' | cut -d '.' -f4 | cut -d '/' -f1 11
コマンドラインが長くなってしまったが、IPアドレスの4つ目[第4オクテット]だけ取得することが出来た。
Linuxのシェルスクリプトを書きます(この例ではファイル名をautorun.shとした)。Raspberry Piの起動直後はIPアドレスが設定されなかったので、IPアドレスを取得できるまで[while文]で1秒毎にIPアドレス取得を繰り返します。取得したIPアドレスの第4オクテットだけを、別のシェルスクリプト[jtalk.sh]で音声合成してラピロに喋らせます。
pi@raspberrypi:/home/pi$ cat autorun.sh #!/bin/sh ipadd="" while [ "$ipadd" = "" ] do ipadd=`ip a show wlan0 | grep "inet " | cut -f6 -d ' ' | cut -d '.' -f4 | cut -d '/' -f1` wait 1 done rtn=`/home/pi/myProgram/jtalk.sh IPアドレスは${ipadd}です`
実行できるようにファイルのパーミッションを変更する。
# ▼変更前 -rw-r--r-- 1 pi pi 291 6月 24 16:46 autorun.sh # ▼変更後 $ chmod +x autorun.sh -rwxr-xr-x 1 pi pi 291 6月 24 16:46 autorun.sh
シェルを実行する。関係ないけど、我が家のトイプードルの名前はシエルです。
$ ./autorun.sh ラピロのスピーカー「IPアドレスは11です。」
成功。ディレクトリのつじつまを合わせるのと、ファイルのパーミッション設定で悩んだけど、起動後にIPアドレスを喋るようになりました。
OS起動時にプログラムを実行するには、Windowsなら[スタートアップ]、DOSなら[autoexec.bat]でした。Linuxだと[rc.local]とか[init.d]とか他にも方法があるとの事。しかーし、Raspberry Pi3のOS(Raspbian Jessie)は[systemd]が推奨されている。設定ファイルを書くのが面倒だけど仕方ない。ディレクトリ「/etc/systemd/system」に自動起動させるためのserviceファイルを作成します。例えば「/etc/systemd/system/autorun.service」という名前の独自ファイルを作って、自動起動したいスクリプトを下記の書式で記載します。
[Unit] Description = Auto Run by Kano [Service] Type=simple ExecStart=/home/pi/autorun.sh [Install] WantedBy=multi-user.target
設定ファイルを書いた後に、ラズパイに覚えさせる手続きがあります。
新しいservice(autorun.service)が存在することを教えます。
$ systemctl daemon-reload
[systemd]コマンドを使ってサービス起動と自動実行の設定をします。
$ sudo systemctl start autorun #スクリプトが動くか検査する $ sudo systemctl enable autorun #次回起動時に実行されるように。
サービスを実行[enabled]するになっていれば、たぶん成功。
$ systemctl list-unit-files --type=service | grep autorun autorun.service enabled
それでは、ラピロの電源をONしてRaspberry Piを再起動させます。
ラピロ『IPアドレスは11ですっ』。やたっ。これで次からIPアドレスが変わっても大丈夫。SSH接続するときにRaspberry Piのアドレスは「192.168.1.11」だということが分かる。
Linux、特にRaspberry Pi3のOS(Raspbian Jessie)では、OSが起動直後にプログラムを実行させる方法としてLinuxのサービスを作る方法だという事が分かった。▽サービスを作成する手順
1.自動実行したいプログラムを作成する。今回はシェルスクリプト[/home/pi/autorun.sh]を作成した。
2.実行するためのパーミッションを設定する。[chmod +x autorun.sh]
3.Serviceファイルを作成する。今回は[/etc/systemd/system/autorun.service]を作成した。
4.[systemctl]で独自サービス[autorun]を覚えさせる。
これで、ラピロが起動した直後に、SSH接続するためのIPアドレスの一部を喋ってくれるようになりました。