たねやつの木

Photos and Programming

[Node.js] Foreverコマンドでスクリプトをバックグラウンドで動かす

079A9455.jpg

できること

タイトル通り。node hoge.jsをバックグラウンドで実行できる。

Raspberry Piの起動時に実行されるスクリプトの中に書き込んでしまえば、 起動と同時に実行されるようになり、デーモンの様になる。

以下の記事の(一応!)続きです(笑)

ココで作成したスクリプトをnodeコマンドで実行すると、 他のコマンドライン操作が一切できなくなりますが、foreverで起動時に バックグラウンドで立ち上がるようにしておけば他のコマンドも実行できるようになります。

Foreverの導入

起動スクリプトはroot権限で実行されるので、グローバルオプションをつけてインストールします。

sudo npm install -g forever

導入自体は以上で完了です。root権限で実行しないとアクセス拒否でエラーとなりインストールできません。

ただ、実際にコマンドライン上でforever hoge.jsと実行してみてもnode hoge.jsとしたときと変わらず、 他のコマンドライン操作ができない状態になります...(笑)。ちょっと思っていた動作と違いますが、もしかしたらオプションでなんとかできるのかもしれません。

Raspberry Piの起動時にforeverで実行するようにする

foreverの導入が済んだので、Raspberry Piの起動時に実行するように設定します。

/etc/rc.localというファイルに書き込んだことが起動時に管理者権限で実行されます。

中身を見てみましょう。

$ cd /etc
$ vim rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

exit 0

このようになっているはずです。よく見てみると、何か処理が書いてあります。 (コメントには何もしないと書いてありますが...(笑)

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

起動時にIPアドレスを表示する処理が書いてあります!これ実はRaspberry Piを箱から出して、 HDMIでモニタに繋いでSSHで繋いだりせずに直接設定を行う時に便利なんですよね(笑)

起動時にサービスの立ち上げがズラズラーと[ok]...と表示される一番最後の方 (ログインユーザー入力のちょっと上)に表示されているので、気になる方はチェックしてみてくださし。


話がそれましたが、先程のIP表示処理の最後(fi)の後に処理を書き込みます。

末尾のexit 0は消さないようにしてください!! 消しても問題無いのかもしれないですが、 触らぬ神に祟りなしです(笑)。この行は処理が処理が正常に完了したということを呼び出し元に返しています。

他のプログラム(Java)で言えばreturn true;といった感じでしょうか。


記述するコマンドはこんな感じです。

[which foreverで表示される内容] [起動したいjsファイル]

そのまんま過ぎて参考にならないですね...(笑) 私の場合はこのようになります。

/usr/local/bin/forever /home/taneyats/nodejs/scripts/dash_button.js

これをrc.localに書き足して、

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

#nodejs forever
/usr/local/bin/forever /home/taneyats/nodejs/scripts/dash_button.js

#DO NOT DELETE EXIT 0!
exit 0

といった感じになります。exitは必ずファイルの末尾に書くようにしてください。(間違って消さないようにコメントを追加しておくのもいいかもしれません。)

上記の内容が何か間違っている場合は、再起動後Raspberry Piの起動処理が正常に完了できずに 最悪一時的にSSH接続などの遠隔からの接続ができなくなる可能性があります。

...ですので、手元にRaspberry Piがある状態で再起動を行ってください。

再起動後、数分待ってもSSH接続などができない場合は、Raspberry Piに直接HDMIとキーボードを挿して、 rc.localファイルを修正してください(_)

以前別の処理を書き込んだ時にこの状態に陥ってヒヤヒヤしたことがあります...orz

動いているか確認する

前回の記事でDash Buttonのスクリプトを作成しているのであれば、ボタンを押せばスクリプトが正常に バックグラウンドで動いているかを確認できます。

あるいは、forever listと打っても確認できます。

info:    Forever processes running
data:        uid  command         script                                      forever pid id logfile                 uptime        
data:    [0] b9ZR /usr/bin/nodejs /home/taneyas/nodejs/scripts/dash_button.js 629     667    /root/.forever/b9ZR.log 1:0:28:10.621

横に長いですが一番右のuptimeの部分が時間を表示していれば動いていることになります。 STOPPEDとなっていれば動いていません。

スクリプトを停止する

内容の変更をしたい時には一度止める必要があります。停止にはforever stopコマンドを使います。

stopの後ろにスペースを一つ開けて、uidを入力します。uidは先程のlistコマンドで表示されているものでおkです。

$sudo forever stop b9ZR
info:    Forever stopped process:
    uid  command         script                                       forever pid id logfile                 uptime        
[0] b9ZR /usr/bin/nodejs /home/taneyats/nodejs/scripts/dash_button.js 629     667    /root/.forever/b9ZR.log 1:0:42:10.835 
$ forever list
info:    No forever processes running

以上で停止の完了です。再度バックグラウンドで起動したいときには...再起動するしかないのかな?(笑)

他にバックグラウンドで実行する手段

私は、screenというコマンドも使います。node.jsではforeverがあるのでコチラは使用しませんが、 node.js以外のスクリプトをバックグラウンドで実行したいときなんかに便利です。

例えば、Minecraftのサーバーを動かしながら、Raspberry Piをコマンド操作した時とか。


また、screenを使うとSSH接続が途切れた際にも処理は続行されるので複数の端末から一つの作業に アクセスしたい時や、長時間の処理を行うときなんかにも便利です。

例では、youtube-dlで一括でファイルをゴニャゴニャしている時に...(笑)

Raspberry Pi 3 Model B

次の記事

現在特に無し(´ε` )