ラベル cron の投稿を表示しています。 すべての投稿を表示
ラベル cron の投稿を表示しています。 すべての投稿を表示

2017年8月2日水曜日

Raspbianで起動時にscriptを自動実行させる

Raspberry Pi 3 Model B (RasPi3)で部屋のLED照明とか、RasPi3自身の冷却ファンのPWM制御とか、室温の計測&loggingをさせている。それらのscriptを起動時に自動実行させたくなったので調べてみた所、以下のwebpageがとても参考になった (というかそのものズバリ)。

* [Raspberry Piでプログラムを自動起動する5種類の方法を比較・解説](http://hendigi.karaage.xyz/2016/11/auto-boot/)

採用した方法と理由


題にもあるように5つの方法が紹介されているが、個人的な用途やpros/consを考えると
cronのjobとして登録する方法が一番のお勧め。

* 登録と削除がcrontab -eで出来て楽
* 起動するscriptはuser権限で起動する

cronを使う時の問題点 (2017-08-25追記)


RasPi3はRTCを持たないので再起動時した直後など暫く時刻がズレていることがある。室温・湿度などをCSV fileに記録する際にはこれが問題となり、本来時系列順であるべき所がいきなり時間が戻ったりする。

19:01:03 ...
19:01:04 ...
18:30:33 ... <--- ここから...
...
18:30:52 ... <--- ここまでおかしい
19:03:12 ... <--- NTPで補正された
19:03:13 ...

cron側でNTPで時刻が補正される迄実行しないようにできれば一番良い。試してはいないが、systemdを使っているのだから依存関係を適切に設定すればNTPの実行後にcronを立ち上げられるような気もする。

取り敢えずsensorから値を取得するscriptの冒頭で、現在時刻とlog fileのmtimeとを比較して、現在時刻がmtimeよりも前 (eg. 現在=16:30でmtime=17:00)なら異常と判断してNTPによるsyncを待つようにした。

発展


もしこれで足りなければ (super userで動かしたいとか)、/etc/rc.localに細工 (exit 0の前あたりに追記)する方法を取る。

正当なやり方はsystemdのserviceとして登録する方法なんだろうけど、たかが小さなscriptを自動実行させたいってだけであんな長ったらしい設定fileを書くのは面倒すぎる。

補足


検索時に気になったのは、あちこちに残っている古い情報が検索の上位に出て来ること。例えばRaspbianのdefault init systemがsystemdに移行したとかの事前情報が無いと、上手く起動しないとか、設定fileが無いとか、無駄に混乱する原因になりそう。

2016年1月31日日曜日

Linux boxでラジオ番組を自動録音する

*** 注意 (2018-12-09追記) ***

この記事は古いため以下の記事を参照されたい:

cf. [Linux boxでラジオ番組を自動録音する]

*** 注意ここまで ***

概要


やりたいこと


Linux boxのline-inに接続されているtunerから流れてくるラジオ番組を自動で録音したい

Solution


  • line-inから録音してOgg Vorbisにencodingするscriptを書く
  • cronに登録して定期的に走らせる

これだけのいたって簡単なお仕事……のはずがどうしてこうなった。

落とし穴と対策


  1. pipeしたprocessの殺し方にハマる
  2. cronのdefaultのshellは/bin/sh
  3. PulseAudio関連のprogramをcronから呼んだ時の挙動にハマる

対策としては:
  1. parec ... | oggenc ... の組み合わせではなくffmpegで録音する → 1、2
  2. 環境変数XDG_RUNTIME_DIRを渡す → 3

わかったこと


  • pipeでつないだprocessesの殺し方
  • parecの他にもffmpegで録音できる
  • PulseAudioを使う時は環境変数に注意

結論


こんな感じのscriptをcronで回している:

# 録音
XDG_RUNTIME_DIR=/run/user/1000 /usr/local/bin/ffmpeg -f pulse -ac 2 -ar 44100 -i
alsa_input.pci-0000_00_1b.0.analog-stereo -acodec libvorbis -q 3 "${FILEPATH}" &
RECPID=$!

# 録音停止
sleep ${DURATION}
kill -TERM ${RECPID}

補足


なお、ffmpegではdurationを指定できるので:

... /usr/local/bin/ffmpeg -f pulse -ac 2 -ar 44100 -i alsa_input.pci-0000_00_1b.0.analog-stereo -acodec libvorbis -q 3 -t ${DURATION} ${FILEPATH} &

とかでも良さそう。また、ffmpegのかわりにparecとoggencを組み合わせても良い:

parec --fix-format --fix-rate --file-format=raw --format=s16ne > >(oggenc -B 16
 -C 2 -q 3 -o "${FILEPATH}" - >/dev/null 2>&1) &

ただし、この方法 (process substitution)はbashやzshでないと使えないので注意が必要。因みに:

parec ... | oggenc ...

とpipeでつないでも良いが、この場合job単位でprocessesを殺す必要がある (kill %%とかで殺せる)ので少々面倒。

補足2


暫くの間:

XDG_RUNTIME_DIR=/run/user/1000 /usr/local/bin/ffmpeg -f alsa -ac 2 -ar 44100 -i
 pulse -acodec libvorbis -q 3 "${FILEPATH}" &

で運用していたが、これだとdeviceの認識順と共にdefaultのsourceが変わって、無音の状態になることがあった。そこでdeviceを限定するため以下のように変更:

XDG_RUNTIME_DIR=/run/user/1000 /usr/local/bin/ffmpeg -f pulse -ac 2 -ar 44100 -i
alsa_input.pci-0000_00_1b.0.analog-stereo -acodec libvorbis -q 3 "${FILEPATH}" &

おまけ


cronで実行したscriptの出力を見ようと思ったら/usr/bin/mailがsymbol lookup errorを吐いた。原因を追求していると本来の目的を忘れそうだったので、とりあえず/var/mail/以下のfileを直接読んで凌いだ。

また、Debian sidだと/usr/bin/mailは/etc/alternatives/mailへのsymlinkであり、これは更に/usr/bin/mail.mailutilsへのsymlinkで、如何なるpackageにも属していない。

参考URL



補足2関連