Funny Snowman

FunnySnowman > Geek<ギーク>なコトをやってみよっと

Raspberry Piの起動直後に、DHCPで割り当てられたIPアドレスを教えるプログラムを自動実行する。

ゴール設定(ラズパイ起動時にラピロがIPアドレスを教えてくれるといいかも)

ラピロの電源を入れる。パソコン側のSSHクライアント「putty」を使って、ラピロのラズパイにssh接続するのだが、時々、SSH接続出来ないことがある。なぜなら、我が家のネットワークはDHCPでIPアドレスが割り当てられるので、定期的にIPアドレスが変わるのです。毎回、arpコマンドで予想してとか、DHMIでディスプレイに繋ぎなおしてとか、DHCPで割り当てられたIPアドレスを調べるのが面倒なので、Raspberry Piが起動した時に、ラピロがIPアドレスを教えてくれるようにしてみる。

SSH(putty)が繋がらない。またIPアドレス変わったか?

実験(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オクテット]だけ取得することが出来た。

実験(IPアドレスをラピロが喋る)

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アドレスを喋るようになりました。

実験(Raspberry Piの起動時に、ラピロが喋る)

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
  

最終検査(ラピロが起動直後にIPアドレスを喋る)

それでは、ラピロの電源をONしてRaspberry Piを再起動させます。

電源ON。ラピロ「IPアドレスは、(192.168.1.)11です」

ラピロ『IPアドレスは11ですっ』。やたっ。これで次からIPアドレスが変わっても大丈夫。SSH接続するときにRaspberry Piのアドレスは「192.168.1.11」だということが分かる。

まとめ(ラピロが起動したら、ラズパイのIPアドレスを教えてくれる)

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アドレスの一部を喋ってくれるようになりました。

▲上に戻る