かつをメモ

自分が書いたプログラムなど色々投稿していきます。

Raspberry Piの起動時にpythonスクリプトをバックグラウンドで自動実行する

こんばんは、かつをです。
前回(Google Home MiniからIFTTTを経由し、Slackに投稿してPS4を操作する - かつをメモ)作成したpythonスクリプトをラズパイの起動時にバックグラウンドで実行するようにし、ssh接続が切断されても動くようにしたいと思います。

バックグラウンドで動かす方法は以下の2通りあるかと思います。

  1. ラズパイ起動時に自動実行
    参考:Raspberry Piでプログラムを自動起動する5種類の方法を比較・解説

  2. nohupコマンドでpython実行
    参考:
    バックグラウンド実行で時間短縮しよう!! - Qiita
    ログアウトしてもバックグラウンド ジョブを継続する方法

2だといちいち自分でコマンドを叩く必要があるので、今回は1でラズパイを動かしたいと思います。

自動実行方法を決める。

以下を参考にしました。

Raspberry Piでプログラムを自動起動する5種類の方法を比較・解説hendigi.karaage.xyz

1. /etc/rc.local
2. autostart
3. crontab @reboot
4. /etc/init.d
5. systemd

今回は3のcrontab @rebootを採用しました。理由はpiユーザーでpythonを動かしたいからです。自分が今までスーパーユーザー権限でpipを叩いてるわけではなく、さらにいくつかのライブラリを直接修正したりしていて、今更sudoでインストールしなおすのが面倒だと思ったからです。

ちなみに1の/etc/rc.localでもpiユーザーで動かすことはできます。以下をご参照ください。

raspbian - Python script fails with 'ImportError' when run from rc.local - Raspberry Pi Stack Exchange

crontabで動かす

早速、以下を入力して動かしました!

@reboot python3 /home/pi/slackbot/run.py

。。。ちゃんと動きません。エラーを確認しようにもログが出力されていないので確認できません。結構詰まりました、どこにログが出力されているかも見つかりません。

1. cronのログを見れるようにする。

cronがちゃんと動いているかどうかまずは確認してみました。以下のコマンドで確認しています。

$ /etc/init.d/cron status
● cron.service - Regular background program processing daemon
   Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2018-09-25 22:35:10 JST; 6min ago
     Docs: man:cron(8)
 Main PID: 352 (cron)
   CGroup: /system.slice/cron.service
           └─352 /usr/sbin/cron -f

 9月 25 22:35:10 raspberrypi systemd[1]: Started Regular background program…on.
 9月 25 22:35:11 raspberrypi cron[352]: (CRON) INFO (pidfile fd = 3)
 9月 25 22:35:11 raspberrypi cron[352]: (CRON) INFO (Running @reboot jobs)
 9月 25 22:35:11 raspberrypi CRON[357]: pam_unix(cron:session): session ope…=0)
 9月 25 22:35:11 raspberrypi CRON[364]: (pi) CMD (python3 /home/pi/slackbot…og)
 9月 25 22:35:17 raspberrypi CRON[357]: (CRON) info (No MTA installed, disc…ut)
 9月 25 22:35:17 raspberrypi CRON[357]: pam_unix(cron:session): session clo… pi
Hint: Some lines were ellipsized, use -l to show in full.

ログが省略されて見にくいのですが、どうやらMTAがインストールされていないというエラーが問題そうです。以下のページでも書かれていました。
Raspberry Piでcronを使った時の話し - Qiita

しかし以下を実行してみましたが、うまく動きませんでした。

$ sudo apt-get install postfix

上記のようにエラー出力がきちんと表示されないのは問題です。logを出力するようにしましょう。以下を参考にしました。
RaspberryPi cronが効かない → ログ表示設定して解決 - min117の日記

下記のコマンドを実行します。

$ sudo vim /etc/rsyslog.conf

そして以下のコメントアウトを解除します。

cron.*                          /var/log/cron.log

これで再起動すれば、ログを残してくれるようになります。実際に再起動して確認して見ます。

$ sudo reboot

以下のコマンドで確認

$ more /var/log/cron.log

ちなみに以下のコマンドで常に監視することが可能です。

$ tail -f /var/log/cron.log
2. pythonのエラーを出力できるようにする。

以下を参照しました。

qiita.com

crontab -eを実行し、以下のように入力しました。

@reboot python3 /home/pi/slackbot/run.py > /home/pi/slackbot/out.log 2>&1

これでエラーも出力されるようになりました。

3. エラー確認と修正

ログを確認して見ましょう。

$ more slackbot/out.log 

start slackbot
Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.5/site-packages/urllib3/connection.py", line 171, in _new_conn
    (self._dns_host, self.port), self.timeout, **extra_kw)
  File "/home/pi/.local/lib/python3.5/site-packages/urllib3/util/connection.py", line 56, in create_connection
    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
  File "/usr/lib/python3.5/socket.py", line 733, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -3] Temporary failure in name resolution

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.5/site-packages/urllib3/connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "/home/pi/.local/lib/python3.5/site-packages/urllib3/connectionpool.py", line 343, in _make_request
    self._validate_conn(conn)
  File "/home/pi/.local/lib/python3.5/site-packages/urllib3/connectionpool.py", line 849, in _validate_conn
    conn.connect()
  File "/home/pi/.local/lib/python3.5/site-packages/urllib3/connection.py", line 314, in connect
    conn = self._new_conn()
  File "/home/pi/.local/lib/python3.5/site-packages/urllib3/connection.py", line 180, in _new_conn
    self, "Failed to establish a new connection: %s" % e)

これで動いてないことが確認できました。ちなみにpythonはフルパスで起動しないと正常に動作しないらしいです。そういえばいろんなサイトがcrontabにフルパスでpythonを実行していました。ちなみに以下を参考にしています。
Raspberry Pi3B でPythonをcronする。 - Qiita

以下のように書き直したら正常に動作しました。

@reboot /usr/bin/python3 /home/pi/slackbot/run.py > /home/pi/slackbot/out.log 2>&1

Google Home MiniからIFTTTを経由し、Slackに投稿してPS4を操作する

こんばんは、かつをです。
今回はGoogle Home MiniからIFTTTを経由してSlackに投稿して、slackbotが投稿内容を見てPS4を操作する、といったことをしたいと思います。slackbotをRaspberry Piに実装し、ラズパイからPS4を操作できるようにします。

続きを読む

MacからSlackbotを立ち上げてPS4を動かす② ps4-wakerの導入〜SlackbotでPS4を動かす

こんばんは、かつをです。
前回( MacからSlackbotを立ち上げてPS4を動かす① Node.jsとnpmのインストール - かつをメモ)は、Node.jsとnpmの導入まで行いました。今回はps4-wakerを導入し、Slackbot-> ps4-wakerでPS4を実際に動かしてみたいと思います。

続きを読む

MacからSlackbotを立ち上げてPS4を動かす① Node.jsとnpmのインストール

こんばんは、かつをです。
MacからSlackbotを立ち上げてPS4を動かす、といったことをしてみたいと思います。動作確認をMacでして、そのままSlackbotのフォルダ構成をRaspberry Piに移す、みたいなことがしたくて今回の記事を書こうと思いました。

続きを読む

Google Home Mini -> IFTTT -> Slackに投稿する

こんばんは、かつをです。
Google Home Miniに話しかけて、IFTTTを経由してSlackに投稿してみたいと思います。

続きを読む

Slackbotを動かしてみる

こんばんは、かつをです。

Google Home Miniを用いて、どうやって家電を動かそうかと考えていました。色々調べてみたところ、Slackを介するのが楽そうだなと思いました。ちなみにHubotを使ってBot作成するのが一般的だそうです。ただ、CoffeeScriptを新たに勉強するのが少し大変そうだと思ったので、とりあえずPythonで書けるSlackbotのライブラリを使ってみようと思います。今やりたいこともこちらで十分そうです。Hubotの方が拡張性は高いのでしょうか?Pythonで書けるというのは自分にとってかなりでかいですね。

続きを読む

Raspberry PiをデスクトップモードではなくCLIで立ち上げる

こんばんは、かつをです。
Raspberry Piには別端末からターミナルでしかアクセスしないので、デスクトップモードではなくCLIで起動するように設定します。

続きを読む