cronでインタラクティブなプログラムを動かしたかった
某所で書籍の貸し出し履歴を追跡するというプロジェクトを動かしていて、バーコードが正しく読み込まれたかどうかのフィードバックや記録そのものにRaspberry Piを利用したい。ISBNに基づいて管理する予定なので、バーコードリーダーの入力を受け取って、「ちゃんとISBNが受け取れていたらOK、そうでなければNG」というフィードバックを返すようなプログラムをPythonで作成。
現場は非エンジニアの人ばかりで、仕事で使っているPCと社内LANからSSH接続して起動するというのは難しそうだったので、
- ラズパイを起動するタイミングでプログラムが実行されるようにcronを設定
- 入力デバイスはバーコードリーダー、フィードバックはSense HatのLEDで表示する
という最小限の構成を組み立てて、これでよし...と思った矢先。
入力を受けられない
入力を受ける前にEOF Errorを吐いてプログラムが落ちてることが分かった。入力デバイスの有無はどうやら関係ないっぽい。EOF Errorということは入力のストリームを待たずして処理しようとしているということで、どうすればいいか全く分からず。
Cronで起動したプログラムはターミナル実行ではない
いろいろ調べていると以下の記事に当たった。
How to run an interactive Python script as cron job?
ものすごくざっくりとした理解なので間違ってるかもしれないけど、要するにcronを利用してプログラムを立ち上げるときはターミナルで実行されてるのではなくバックグラウンドプロセスとして走るので、外部から入力を受けたりすることはできない...ということらしい。
じゃあバックグラウンドプロセスの標準入力はどう扱えばいいんだ?と思いさらに調べたらここに答えらしきことが書いてあった。
バックグラウンドで実行するプロセスの標準入力は・・・ (「torutkのブログ」様の記事より)
上記の記事ではmkfifoコマンドをうまく使って標準入力と標準出力を得るようにしているが、今回自分がやりたいのはPythonのinput()
で入力を受け取ってその内容を判定して...というような処理を回すことで、その辺の処理は全てPythonのプログラム中で完結させたいので、もう少し何か工夫が必要っぽい。
他にもcronに設定する段階で標準入力を /dev/null
で指定するとうまくいくとかいかないとか...
バックグラウンドプロセスの標準I/Oはめんどくさい?
単に自分の知識不足な感はあるものの、バックグラウンドプロセスに積極的に入力を渡すのはあまり得策ではなさそう、という知見は得られた。