この記事は、Linux Advent Calendar 2016の記事です。
CentOS 7でデジタルサイネージみたいなものを作ったので、それを記事にします。
デジタルサイネージと言って、下記のイメージを持たれた方はそっと閉じられた方が良いかもしれません。
実際はこんな感じです。
「PCを起動すると、あるプロセスの標準出力を出し続ける」環境を構築する手順をご紹介します。
動機
この記事では実用性は皆無ですが、これの発展版を社内で使っています。
詳細は伏せますが、「一般社員は何もできない」「でも限られた操作と表示はしたい」
みたいな場合に使えるのではないかと思います。
環境
CentOS 7.1 を使います。
CentOS 7系は、Systemdが採用されており、プロセスのデーモン化がかなり簡単になったと思います。
スクリプトを書かずに、設定ファイルを書いていく感じです。
私はupstart時代にデーモン化をしたことが無いゆとりなので、正確な比較はできませんが・・・
仕様
デジタルサイネージなので、電源を付けるだけで画面の表示までやってくれるようにします。
ログインやその他の操作を不要にします。
また第三者になるべく操作されたくないので、rootでログインしない限り一切コマンドを実行できないようにします。
設計
画面への表示方法としては
- 標準出力をファイルにリダイレクトし、そのファイルを
tail -f
などで出力する方法 - 標準出力をttyコンソールに直接リダイレクトする方法
の2つがありますが、今回は後者の直接リダイレクトを採用します。
なぜなら、ログファイルの削除やログインスクリプトの作成といった工数が減るためです。
(後述しますが、Linuxのログインスクリプトで引数を取ることができません)
もしログファイルを残しておきたいのであれば、前者の方が適切でしょう。
作成するものは下記です。
- ひたすら「Hello World」と出力するだけのプログラム
- 上記をサービス化するための設定ファイル
- 出力を受け取るためのログインユーザー
- 自動ログインするための設定ファイル
なお、今回作成するアプリケーション名はsignage
とします。
ひたすら「Hello World」と出力するだけのプログラム
#!/bin/sh
echo 'Hello World'
実際のアプリケーションでは、ここが天気予報だったりニュースだったりするでしょう。
サービス化
上記のスクリプトをサービス化するための設定ファイルを作ります。
[Unit]
Description = digital signage
After=network.target remote-fs.target nss-lookup.target
[Service]
Type = oneshot
ExecStart = /bin/bash -c '/opt/signage/main.sh > /dev/tty1'
[Install]
WantedBy = multi-user.target
After=
でネットワークが有効になった後にこのサービスを開始するよう指定しています。
後に天気予報を表示するなどした時に、ネットワークが必要になるためです。
システム同士の関連が分かりやすくて良いですね。
Type = oneshot
という洋画のような記述は、この場合 simple
の方が良いかもしれません。
ExecStart
では、作成したスクリプトを実行し、その出力先を/dev/tty1
にします。
/dev/console
も試したのですが駄目でした。
WantedBy=
では、CentOS6系で言うところのランレベル3以上で起動するようにしています。
このサービスを、自動起動するよう設定します。
sudo systemctl enable signage.service
ログインユーザーを作成する
次に、自動でログインするためのユーザーsignage
を作成します。
sudo useradd signage
このユーザーには一切の操作をさせたくない、でもログインはできるようにしたいので、
ログインスクリプトにtail
を指定します。
tail
にしている理由は無く、/bin/bash
とかじゃなかったら何でも良いです。
signage:x:1001:1001::/home/signage:/bin/tail
試しにsudo su - signage
などとすると、何もできないでしょう。
ちなみに、このログインスクリプトで引数を取ることはできませんでした。
/bin/tail /var/log/messages
とか"bin/tail /var/log/messages"
とかやってみましたが駄目でした。
自動ログイン
※この部分は全く自信が無いので、間違っていたら教えてもらえると嬉しいです。
CentOS7では、getty
というサービスがログインを管理しているみたいです。
getty@tty1.service
が各/dev/tty1
へのログインを管理しているようです。
ちなみに、ネットワークを管理しているのはNetworkManager
というサービスで、
各インターフェースを管理しているのはNetworkManager@eth0.service
などとなっています。
分かりやすいですね。
で、getty@tty1.service
の設定をoverrideすることで、自動ログインを可能にします。
[Service]
ExecStart=-/sbin/agetty --autologin signage --noclear %I 38400 linux
引数を解説しようと思ったのですが、ここは呪文的に書いてしまったので分かりません・・・すみません。
%Iは、対象のtty(この場合はtty1)が入るらしいです。
起動
再起動して、延々とHello World
が表示されるのを確認しましょう。お疲れ様でした。
参考
- http://enakai00.hatenablog.com/entry/20130917/1379374797
- https://bbs.archlinux.org/viewtopic.php?id=169483
- http://unix.stackexchange.com/questions/150975/what-is-needed-for-a-minimal-systemd-boot-to-launch-getty-on-a-virtual-console
- http://askubuntu.com/questions/659267/how-do-i-override-or-configure-systemd-services