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

2017年11月17日金曜日

Raspberry Pi+Raspbian stretchでwkhtmltopdfを使ったホームページ画像化しGoogleフォトにアップロードする

事の発端は毎週のダイエットサマリーブログ

毎週掲載しているダイエットサマリーブログで、体組成データや筋トレチェック表を画像化して掲載しています。
以前ご紹介した画像化の方法でしばらく使っていたのですが、OSアップデートによる変更で動作しなくなったり、SDカードの破損で運用そのものが危ぶまれたり、踏んだり蹴ったりのトラブル続出で使用中止していました。
代替案で、他の端末からスクリーンショットをアップロードして使っていたのですが、その作業がとにかく面倒くさい😭
Raspbian stretchで強化されたセキュリティ関連のクセが、やっとここに来て飲み込めて来たので楽したくて再チャレンジしました😤

wkhtmltopdfに巡り合う

あれこれ探した末に見つけたのがwkhtmltopdfでした。
Google製のアプリで、HTMLレンダリングエンジンWebkitを使って展開し、それをPDFや画像ファイル化するためのものです。
対応OSもWindows・macOS・Linuxに対応しているので、私のようにあれこれ使う人にとってはとても助かります。

Raspbian stretch LITEにインストールするも動かず

インストール方法は、おなじみのaptを使います。

sudo apt-get install wkhtmltopdf
使い方は、下記のコマンドです。
wkhtmltoimage [URL] [画像ファイル]

Raspberry Pi Zero Wで使ってみたのですが、下記のようなエラーが出て動きません。

QXcbConnection: Could not connect to display
中止
フレームバッファが必要なのかも。

仮想フレームバッファ Xvfbで実行

前回画像化でも使った仮想フレームバッファ Xvfbを今回も使います。
まずは、インストール。

sudo apt-get install xvfb
次に、仮想フレームバッファをこのアプリで作成し、そこでwkhtmltopdfを実行します。
xvfb-run -a -s '-screen 0, 1024x768x24' wkhtmltoimage [URL] [画像ファイル]
これで、どんな環境でも使えると思います。

出来た画像ファイルをupload-gphotosGoogleフォトへアップロード

使わせていただいているブログサイト Bloggerの記事作成機能はとても便利で、Googleフォトの画像も直接貼り付けられます。
そこで、HTMLから作った画像を、upload-gphotosGoogleフォトへアップロードします。

upload-gphotosはTypeScriptで書かれていますが、JavaScriptへトランスパイルされたモノがnpmでインストール可能なので、今回はそれを使わせていただきます。

node.js、npm、nを最新に

Raspbianに標準インストールされているパッケージが古く、そのままでは動きません。
そこで、最新版のインストール作業から始めます。

まず、パッケージリストを更新します。

sudo apt-get update
次に、npmをインストール。
sudo apt-get install -y npm
次に、npmの最新版をインストール。
sudo npm install -g npm
npmをnpmでインストールってなんかだか不思議な感じですけどね😅
このブログを書いてる段階のRaspbian最新版September 2017では、下記のようなエラーがでます。
/usr/bin/env: ‘node’: No such file or directory
これは、node.jsのコマンドであるnodeがないために出るエラーです。nodejsという古い名前のままなので、nodeという名前でリンクを作ります。
sudo ln -s /usr/bin/nodejs /usr/bin/node
そして、再びnpmの最新版をインストールするコマンドを実行すると処理が始まります。 npm最新版になったら、次はnode.jsのバージョン管理パッケージnをインストール。
sudo npm install -g n
やっと、本題の最新版node.jsのインストールです。
sudo n stable
もし、最新バージョンがリリースされているにも関わらずError: invalid version~というエラーが出た場合、そのバージョンのターゲットCPUのパッケージがまだアップロードされていない可能性があります。
Raspberry Piは、現段階でARMv6/7/8の3種類のCPUアーキテクチャ商品があります。Raspberry Pi 2 V1.2と3(コンピュータモジュール含む)がARMv8、Raspberry Pi 2 V1.1がARMv7、その他はARMv6です。ARMv8は64bitアーキテクチャなのでARM64としてリリースされてる事が多いですが、Raspbianは互換性維持のために32bitで動かしているので実質ARMv7と思って良いと思います。
ご使用のRaspberry Pi用CPUアーキテクチャパッケージがアップロードされていない場合は、
sudo n [バージョン番号]
直接バージョン番号を指定してインストールしてください。
あるかどうかの確認は、ダウンロード先のnodejs.orgにブラウザでアクセスし、バージョン毎にディレクトリ(フォルダ)が分かれているので、その中にlinux-arm~l.tar.gzってのがあるか確認し、ある中から最新バージョンのモノを指定してください。
念のため、インストールしたnode.jsのバージョンを確認しておいてください。
node -v
もし、古いバージョンのままの時はリンク先が古いものを指してるはずですので、最新版に変更すればOKです。

upload-gphotosをインストール

ここまで来たらもう一息!
upload-gphotosのページの下のInstallationのnpm (Recommended)を参考にインストールします。
スーパーユーザーでインストールするので、sudoを付けて実行してください。

sudo npm install -g upload-gphotos
使い方はこんな感じ
upload-gphotos [画像ファイル名] -u [Googleフォトユーザー名] -p [パスワード] 
ログインエラーが出た場合、安全性の低いログイン技術を使ったアプリの利用許可がされていない可能性があります。 安全性の低いアプリによるアカウントの使用を許可するの説明を参考に、安全性の低いアプリの許可にアクセスして有効にしてください。

シェルスクリプトでサクッと実行

準備は整ったので、これを組み合わせて簡単に実行でいるシェルスクリプトを作ります。
便宜上スクリプト名はhtml2pngとします。

nano html2png
#!/bin/bash
# 一時ファイルを作る
tmpfile=$(mktemp --suffix=.png)

function rm_tmpfile {
  [[ -f "$tmpfile" ]] && rm -f "$tmpfile"
}
trap rm_tmpfile EXIT
trap 'trap - EXIT; rm_tmpfile; exit -1' INT PIPE TERM

xvfb-run -a -s "-screen 0, 1024x768x24" wkhtmltoimage --width $2 $1 "$tmpfile"
upload-gphotos "$tmpfile" -u [ユーザー名] -p [パスワード]
出来たら実行権限を追加します。
chmod +x html2png
使い方はこんな具合。
html2png [URL] [横幅px]

upload-gphotosでちょっと気になった不具合

例によって、Raspberry Pi Zero W+Raspbian Stretch Ver.September 2017ベースで試していたのですが、upload-gphotos実装直前までこぎつけて不具合を見つけました。それは、他のRaspberry PiからSSHコマンドを使ってリモート実行した時に起こりました。

1つ目は、アップロード時のプログレッシブバーが表示されません。
wkhtmltopdfのプログレッシブバーや他の文字は表示されているので、upload-gphotosで使われてるモジュール固有の問題のようです。
原因を調べてみると、TTYチェックしてる部分があってそうじゃない場合はそもそも表示しないようなのです。
なぜ除外してるかさらに調べた所、1行の長さを取得してる部分があってそれがTTYじゃないと取得できず、仮にチェックを無効にしてもその後の処理でエラーになってしまいました。
まぁ、仕様通りの動作ですし、進捗状況が未表示でも問題ないので、このまま使わせていただく事にしました。

問題だったのはもう1つの不具合でした。
アップロード終了後に諸々の情報を表示して終わるのですが、それがSSHコマンドからの直接実行だと終わらないのです。
通信処理を非同期で行っていて、それをメインモジュールで同期モードで動かしてるようなのですが、TypeScriptとJavaScriptのトランスコンパイルの部分で仕様差が吸収出来てないような気がしました。
そのままではいろいろ困るので、cli.ts(cli.js)の末行付近にある

console.info(JSON.stringify(photos, null, 2));
の次の行にプロセスの終了命令を追加しました。
process.exit();
これで、終了しない不具合は解消されました。

最後の最後でまさかの!?

やっとブログも書き終わる!と思った矢先に、まさかの不具合発覚。
曜日が表示されていないのです。なぜ?どうして??
原因は簡単でした。日本語フォントがインストールされてなかったんです😅
ということで、Google Noto Fontsをインストール。
sudo apt-get install -y fonts-noto

無事に曜日が表示されました。

お読み頂きありがとうございました。
次回もお楽しみに!

2016年8月31日水曜日

Raspberry Pi+RaspbianでHTMLを画像化 する

Twitterは140文字の制限があるため、 URL分の23文字を消費するかわりにそれ以上の情報を画像として掲載する事があります
私のアカウントでも 自前のホームページ(HTML)を画像化して良く掲載するのですが、それをRaspberry Pi + Raspbianで作っています。
今回はその作り方を紹介します。

CutyCaptをインストール

まずCutyCaptをインストールします。

$ sudo apt-get install cutycapt⏎
インストールができたら試しに実行してみます。
$ cutycapt⏎
cutycapt: cannot connect to X server
するとこういうメッセージが出ます。X serverに接続できませんでしたというメッセージです。
このアプリはX Window Systemと呼ばれるLinuxではメジャーなGUIが使われている ため、CLIで実行するとこのようなエラーメッセージが表示されてしまいます。
このままでは使えないため、X Window System をCLIで仮想的に動かすソフトをインストールします。

Xvfbをインストール

X Window SystemをCLIで仮想環境を作り出すXvfbをインストールします。

$ sudo apt-get install xvfb⏎
インストールが完了したら試しに実行してみます。
$ xvfb-run --auto-servernum --server-args="-screen 0, 1024x768x24" cutycapt⏎
Xlib:  extension "RANDR" missing on display ":99".
 -----------------------------------------------------------------------------
 Usage: CutyCapt --url=http://www.example.org/ --out=localfile.png
 -----------------------------------------------------------------------------
  --help                         Print this help page and exit

〜 省略 〜

  --http-proxy=             Address for HTTP proxy server (default: none)
 -----------------------------------------------------------------------------
   is svg,ps,pdf,itext,html,rtree,png,jpeg,mng,tiff,gif,bmp,ppm,xbm,xpm
 -----------------------------------------------------------------------------
 http://cutycapt.sf.net - (c) 2003-2010 Bjoern Hoehrmann - bjoern@hoehrmann.de
こんな感じで表示されれば成功です。

HTMLを画像化してみる

まず、 画像化するためのホームページを用意します。
今回は 説明の便宜上、このホームページURLをhttp://localhost/weightview.phpとします。

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

$ xvfb-run --auto-servernum --server-args="-screen 0, 1024x768x24" cutycapt --url=http://localhost/weightview.php --out=out.png⏎
--url=が画像化するURL、--out=が出力する画像ファイル名です。

実行したディレクトリ直下にout.pngというファイルが出来ます。
もし、余白が気になるようならオプションで--min-width=が横幅 --min-height=が縦幅で指定すると縮める事が出来ます。

シェルスクリプトで簡単実行

Xvfb +cutycaptを毎回コマンドラインで 打つのは長いですよね。
そこで、それを簡単に使うためのシェルスクリプトを作ります。

$ nano html2png⏎
↓↓↓ 編集内容 ↓↓↓
#!/bin/bash
/usr/bin/xvfb-run --auto-servernum --server-args="-screen 0, 1024x768x24" \
/usr/bin/cutycapt --url=$1 --out=$2 --min-width=$3 --min-height=$4
↑↑↑ここまで↑↑↑
 $ chmod +x html2png⏎
これで出来上がり。
試しに実行してみます。
$ html2png http://localhost/weightview.php out.png 800 800⏎
これで画像が できたら完成です。

応用範囲が結構広い

今まではクライアントコンピュータのOSのスクリーンショット撮影機能で対応していたのですが、毎回それが手間 でした。
また、範囲指定もマウスでゴリゴリするので、微妙に差が ありました。

今回の仕組みを作ってからSNSへのアップロードも楽ちん♪
画像レイアウトも作ろうか検討中です。

2016年8月9日火曜日

Raspberry Pi 2+RaspbianでOpen JTalk Ver.1.09をコンパイルしインストール

前回Raspberry Pi 2+Raspbianをお話できるようにしましたにて 、Open JTalk Ver.1.07をインストールしました。
しかし、この バージョンでは音量オプション -gが使えません。

そこで、今回は最新版であるOpen JTalk Ver.1.09をコンパイル・インストールして使えるようにしてみたいと思います。
hts_engine APIをコンパイル
Open JTalkhts_engine API を使っています。
Open JTalkコンパイルに先立って、まずコレをコンパイルします。
ディレクトリをホームに戻します。
$ cd
ソースコードをダウンロードします。
$ wget http://downloads.sourceforge.net/hts-engine/hts_engine_API-1.10.tar.gz
そして、これを解凍します。
$ tar zxvf hts_engine_API-1.10.tar.gz
解凍が終わったら解凍したディレクトリに移動します。
$ cd hts_engine_API-1.10
コンパイルのための設定ファイルを作ります。
$ ./configure
できたらコンパイルします。
$ make
完了すると/home/pi/hts_engine_API-1.10に実行日の日付で新たなファイルが 追加されたりします。
作業が完了したら、次の作業のためにcd⏎でホームディレクトリに戻しておいてください。
Open JTalk Ver.1.09をコンパイル
Open JTalkのサイトからVer.1.09のソースファイルをダウンロードします。
$ wget http://downloads.sourceforge.net/open-jtalk/open_jtalk-1.09.tar.gz
解凍します。
$ tar zxvf open_jtalk-1.09.tar.gz
解凍先 のディレクトリに移動します。
$ cd open_jtalk-1.09
コンパイルのための設定ファイルを作ります。
下記コマンドは改行せず1行で入力してください。
もし、長すぎて改行したい場合は\(バックスラッシュ)を区切る行末に入れるとできます。
$ ./configure --with-charset=UTF-8 --with-hts-engine-header-path=/home/pi/hts_engine_API-1.10/include --with-hts-engine-library-path=/home/pi/hts_engine_API-1.10/lib
できたらコンパイルします。
$ make
動くかどうか確認してみます。正常な場合はVer.1.09の確認が出来ます。
$ ./bin/open_jtalk
root権限でインストールします。
$ sudo make install
動くかどうか確認してみます。 パスが通っていれば下記コマンドのみで実行可能なはずです。
通ってない場合はフルパス/usr/local/bin/open_jtalkで実行してみてください。
正常な場合はVer.1.09の確認が出来ます。
$ open_jtalk
作業が完了したら、次の作業のためにcd⏎でホームディレクトリに戻しておいてください。
Open JTalk 辞書ファイルをコピーする
Ver.1.07の辞書ファイルをそのまま使う事も可能ですが、Ver.1.09の辞書ファイルは若干容量が増えているので何らかの追加がされてるようです。
そこで、最新の辞書ファイルをコピーします。
Open JTalkのサイトからVer.1.09の辞書ファイルをダウンロードします。
$ wget http://tenet.dl.sourceforge.net/project/open-jtalk/Dictionary/open_jtalk_dic-1.09/open_jtalk_dic_utf_8-1.09.tar.gz
解凍します。
$ tar zxvf open_jtalk_dic_utf_8-1.09.tar.gz
root権限でコピーします。
$ sudo cp -r open_jtalk_dic_utf_8-1.09 /var/lib/mecab/dic
前回Raspberry Pi 2+Raspbianをお話できるようにしましたにて作成したjsayを書き換えます。
$ nano jsay
修正箇所は下記の赤字の箇所の部分
#!/bin/bash
tempfile=`tempfile`
echo "$1" | open_jtalk -m /usr/share/hts-voice/mei/mei_normal.htsvoice -x /var/lib/mecab/dic/open_jtalk_dic_utf_8-1.09 -ow $tempfile
aplay -q $tempfile
rm $tempfile
CTRL+X→Yで保存終了。
実行出来るかどうか確認してみます。
$ jsay 本日は晴天なり
特段これといった変化はないのですが、動作確認 の意味でやってみてください。
音量を変えてみる
Ver1.09で追加された音量オプション -gを試してみます。
jsayスクリプトに オプションを追加します。
$ nano jsay
修正箇所は下記の赤字の箇所の部分
#!/bin/bash
tempfile=`tempfile`
echo "$1" | open_jtalk -g $2 -m /usr/share/hts-voice/mei/mei_normal.htsvoice -x /var/lib/mecab/dic/open_jtalk_dic_utf_8-1.09 -ow $tempfile
aplay -q $tempfile
rm $tempfile
CTRL+X→Yで保存終了。
音量が変わるかどうか確認してみます。
音量が小さくなっていれば 成功です。
$ jsay 本日は晴天なり -20
音量は+数字で音量が大きくなり、-数字で小さくなります。
オマケでマスターボリュームの 変え方
マスターボリュームの変え方は2種類あります。
視覚的に変更する場合はこのコマンドで出来ます。
矢印キー↑↓で上げ下げできます。
$ alsamixer
次に、コマンドラインのみで直接変える方法です。
%の所の数字を大きくすると音量も大きくなり、小さくすると音量も小さくなります。
$ amixer cset numid=1 90%
なお、現在の 音量を確認したい場合は、%の数字を書かずに実行すると valuesの数字で確認できます。
表示になるminとmaxは%指定では なく数字で指定した場合の有効範囲です。
最後に
Open JTalkをRaspberry Pi+Raspbianにインストールする方法を解説した記事は他にもあります。
今回あえて執筆した理由は、バージョンアップによって音声定義 ファイルが.htsvoiceに変更になり、やり方が変わったため最新の手順ということで書きました。
ネット上には古いタイプの音声定義ファイルも残っていてそのままでは使用できません。
もし試してみたい場合は、.htsvoiceに変換する必要があります。
その手順に ついては、既存の記事で対応出来るようなので探して みてください。

2016年8月5日金曜日

Raspberry Pi 2+Raspbianをお話できるようにしました

Raspberry Piの処理結果を得る方法は色々考えられます。
その中から今回は音声合成を使った音の出力をしたいと思います。
準備
今回はRaspberry Pi 2を使います。
Raspberry Pi 2は、音声出力の方法としてHDMIとステレオミニジャックの2種類あります。
スピーカー内蔵モニタならHDMIを、音声のみならステレオミニジャックにスピーカーを接続すると良いでしょう。

ステレオミニジャックを使う場合、出力レベル(音量)がとても低く、イヤホンを使ってやっと聞ける程度です。
大きい音を出したい場合は、相応のスピーカーとアンプが別途必要になります。
接続したのは、100円ショップで購入したモノラルスピーカーx2台でステレオ化したモノとヘッドホンアンプ FiiO E5です。
家にあったものを流用しただけなので、新たに購入されるならアンプ内蔵のモノが安く売られてるのでそちらのほうが良いでしょう。
音声合成ソフト Open JTalk Ver.1.07をインストール
OSは標準的なRaspbianを使っています。
Open JTalkは、入力された文字を元に音声ファイル(wavファイル)を作る音声合成ソフトです。
インストールするパッケージ3つ
  • open-jtalk(Open JTalk本体)
  • open-jtalk-mecab-naist-jdic(辞書)
  • hts-voice-nitech-jp-atr503-m001(音声データ)
コマンドラインから下記をコピペしてインストールします。
$ sudo apt-get install open-jtalk open-jtalk-mecab-naist-jdic hts-voice-nitech-jp-atr503-m001
試しに実行
コマンドラインから下記をコピペして実行します。
$ echo "本日は晴天なり" | open_jtalk -m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice -x /var/lib/mecab/dic/open-jtalk/naist-jdic -ow test.wav
すると、実行した直下にtest.wavというファイルが出来ているはずです。
出来たファイルをパソコンで再生しても良いですし、Raspberry Piで再生する場合は下記のようにすると再生できます。
$ aplay test.wav
もし、再生した音量が小さい場合は調整してみてください。
$ amixer cset numid=1 100%
100%の部分を減らすと音量が下がり、増やすと音量が上がります。
視覚的に調整したい場合は下記コマンドでも出来ます
$ alsamixer
音声合成ファイル作成と再生をするシェルスクリプトを作る
コマンドラインで任意のテキストをお話させるシェルスクリプトを作ります。
スクリプト名はなんでも良いのですが、便宜上jsayとします。 エディタを起動します。
$ nano jsay
起動できたら下記のコードをコピペします。
#!/bin/bash
tempfile=`tempfile`
echo "$1" | open_jtalk -m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice -x /var/lib/mecab/dic/open-jtalk/naist-jdic -ow $tempfile
aplay -q $tempfile
rm $tempfile
コピペできたら、CTRL+X→Yで保存終了。
出来たシェルスクリプトに実行パーミッションを付加します。
$ chmod +x jsay
できたら試しに実行してみます。
$ jsay 本日は晴天なり
もし、お話させる文字列にスペースが入っていたりする場合はダブルコーテーション(")で括ってあげれば渡す事が出来ます。
女性の声に変えてみる
今度は女性の声で喋らせてみたいと思います。
MMDAgentのmeiという ボイスデータを使わせていただきます

まず、MMDAgentのサイトからSourceForge上に掲載されてるzipファイルをダウンロードします。
$ wget http://tenet.dl.sourceforge.net/project/mmdagent/MMDAgent_Example/MMDAgent_Example-1.6/MMDAgent_Example-1.6.zip
ダウンロードが完了したら 解凍します。
$ unzip MMDAgent_Example-1.6.zip
解凍したディレクトリMMDAgent_Example-1.6直下にある/Voice/meiディレクトリをまるごとrootオーナー/usr/share/hts-voiceにコピーします。
$ sudo cp -r ./MMDAgent_Example-1.6/Voice/mei /usr/share/hts-voice
jsayシェルスクリプトの-mオプションを変更します。
$ nano jsay
修正箇所は下記の赤字の箇所の部分
#!/bin/bash
tempfile=`tempfile`
echo "$1" | open_jtalk -m /usr/share/hts-voice/mei/mei_normal.htsvoice -x /var/lib/mecab/dic/open-jtalk/naist-jdic -ow $tempfile
aplay -q $tempfile
rm $tempfile
CTRL+X→Yで保存終了。
なお、実行パーミッションは変わらないのでそのままで大丈夫です。
できたら再び 試してみます。
$ jsay 本日は晴天なり
女性の声に変わりましたか?
meiの音声ファイルは今回変更したmei_normal.htsvoiceの他に、mei_angry.htsvoicemei_bashful.htsvoicemei_happy.htsvoicemei_sad.htsvoice などが あります。
-mの箇所を適宜変更して 聴き比べてみると良いでしょう。
気圧温度湿度センサー BME280の取得情報を 報告 させてみる
以前このブログで紹介した気圧温度湿度センサー BOSCH BME280で記録している情報をOpen JTalkで報告させてみました。



やり方は、センサーから読み取った 数字を喋らせたい定型文に埋め込み、それをjsayを使って喋らせています。
この要領で色々な活用方法が出来るでしょう。
音声合成ソフト Open JTalk Ver.1.07の 音量調整の難点
今回インストールしたOpen JTalk Ver.1.07 は古いバージョンで、最新はVer.1.09です。
単に喋らせるならば Ver.1.07でも問題なく使用できます。
それに対し、最新版のVer1.09には音量が調整できる-gオプションが追加になっています。
このオプションがあると他のアプリとの音量バランスの調整が可能になるため、 例えばBGM を再生中に強調した発声をさせてお知らせするような事が可能になります。
ただ、Ver.1.09は今回の インストールで使ったaptにはパッケージ登録されていないため 、自前で必要なファイルを用意してコンパイルしインストールする必要があります。

次回は、この手順について 書きたいと思います。

2016年7月5日火曜日

Raspberry Pi ZeroにOS Raspbianをセットアップ

前回までのトゥエンティー、、、ゲフン。
Raspberry Pi ZeroにGPIOのピンヘッダーをハンダ付けしてケースに組み付けた所までやりました。
ただ、このままだとSDカードが抜き挿し出来ないので、面倒ですがセットアップ中は一旦ケースから出して使いました。
ケーブルの取り付け
前回までに用意した変換コネクタやケーブル類、あと自宅にあるモノいくつか使って接続していきます。
HDMIはモニタ用のケーブル。microUSBコネクタは2つ付いてますが、真ん中のが周辺機器用でハジのが電源用です。

microUSBはそのままではタイプAと呼ばれる一般的なコネクタが物理的に挿せないので、microUSB変換ケーブル(OTGケーブル)を使って繋ぎます。
また、周辺機器用のコネクタが1つしかないのでUSBハブ経由となりますが、電流容量500mAが上限なので十中八九足りなくなります。
そのため、セルフパワータイプのUSBハブを使ったほうが無難でしょう。

今回取り付けたUSB機器はこちら
  • ワイヤレスキーボード
  • 有線マウス
  • 1000BASE-T有線LANアダプタ
microSDカードにOS Raspbianのイメージファイルを復元
今回もRaspberry Pi財団のRaspbianを使います。

まず、用意したSDカードをSD Formatterでフォーマットします。
これをする理由は、SDカードのチェックと不良セクタ(不良素子)を弾くのが狙い。
新規にイメージ展開する時も、バックアップイメージを展開する時も、この作業は必ずやったほうが良いです。

次に、ホームページからイメージファイルをダウンロードし、インストレーションガイドを参考にイメージファイルをSDカードに展開します。
展開し終わったらSDカードを本体に戻します。
目覚めよ!Raspberry Pi Zero!!
電源を入れてイザ起動!
もし、ここで運悪く接続漏れとか発覚して途中で電源を切ってしまうと、最悪SDカードに展開したイメージが破損します。
SDカードが物理的に壊れたわけではないので、その時はまた再セットアップしましょう

無事立ち上がるとGUIが立ち上がります。
初期設定では英語なので、左上のMenuをクリックしてPreferencesをクリック。
一番下のRaspberry Pi Configurationをクリックすると設定画面が開くので、上の右側にあるLocalisationタブをクリック。
そこで日本語設定します。

ただ、これだけだと文字化けするので、ターミナル(上にあるモニタみたいなアイコン)をクリックし、
$ sudo apt-get install ttf-kochi-gothic xfonts-intl-japanese xfonts-intl-japanese-big xfonts-kaname
と入力してフォントをインストール。再起動すると文字化けしなくなります。
コマンドラインも四角い文字で文字化けしますが、これはjfbtermというソフトをインストール・起動すると解決するのですが、そちらは別のサイトで解説されてるので検索して調べてみてください。
Raspbianを自分色に染め上げる
Raspberry Pi ZeroにRaspbianをセットアップして無事起動。
ただ、私は普段CLI(コマンドライン)しか使わないので、この後Configurationで起動時のモードをCLIにしたり、短縮コマンドのAliasを設定したり色々やります。
一通り済んだら念のためそこでイメージバックアップを取って作業終了。
今回は凝ったことしないお体なのであっさり終わりました。

一応、これでRaspberry Pi Zeroのスタートアップの話は終わりです。
次回は、作業中にわかったオマケ記事を書きたいと思います。

2016年4月21日木曜日

Raspberry PiのLinux、Raspbian atコマンドで学んだshとbashの問題

Raspberry Pi Zeroが日本国内販売はおろか、本家イギリスでも相変わらず入手困難な状況が続いているようです。
そんな中、突如発表発売されたRaspberry Pi 3
ARM Coretex-A53を採用したSoC Broadcom BCM2837を搭載し、Raspberry Pi初となる64ビット機となります。また、無線LANBluetoothも搭載されコレも初。

今後も目が離せませんね♪
Linux三昧
Raspberry Pi 2を購入して以来その魅力に取り憑かれてしまい、オフィシャルOS Raspbianを通じてLinuxが楽しくて仕方ない今日このごろ。
こんな事したら楽しいかな?あんな事したら便利かな?を形にすべく、時間を見てはチョコチョコいじっています。

そんなLinuxには色々便利機能があるのですが、その中の1つにatコマンドというのがあります。

Raspbian標準では入ってなくて、Debian向けに開発されたパッケージ管理システム APTを通じてインストールする事が可能です。

$ sudo apt-get install at

こんな感じでコマンドラインから打ってやるとインストールできます。
atコマンドで出来る事
そもそも、このコマンドで何が出来るか?というと

指定した日時に1度だけ実行できる

Raspbian標準でcrontabという似たコマンドがあり、やろうと思えばこちらでも同様の事が可能です。
しかし、crontabでatと同じ事をしようとした場合、

実行し終わったらスケジュールリストから自力で削除しなければならない

crontabはシステムが稼働中にスケジュール条件のジョブがあった場合に実行するコマンドです。
定期的に動かさなければならない場合に使う事が多いので、1回コッキリの作業にはあまり向かないコマンドです。
うまく動いてくれないジョブ
便利なatコマンドは何度も使っていて、勝手知ったるツモリでこの日もパチパチ作っていました。
登録するジョブのシェルスクリプトを手動でテスト実行したら想定通りの動作。
いざ、本番を想定したatコマンド登録して1分後に実行するようセット。


・・・
・・・
・・・

ただのシカバネのようだ。


ウンともスンとも言いません。
何か間違ってるのかと思い、手動実行するもちゃんと動きます。
実行ユーザーの差も疑ってsudo付けて実行しましたがやっぱりちゃんと動きます。
難航するデバッグ作業
atコマンドは通常は標準出力に文字を表示してくれません。
何かあればメールでメッセージが入ってくる事があるのですが、今回はそれもありません。
今回実行しようとしたシェルスクリプトは、sourceコマンドで別の関数をライブラリ化したシェルスクリプトを読み込んで使うモノでした。
それが上手く動作していないのかと思ったのですが見当ハズレ。
単独で動いた簡単なコード

echo "test" > out.log

これ1行のみのコードの関数を作り、それをsourceコマンドで読み込んでメインスクリプトで実行すると上手くいきます。

もう何が悪いのかわからないヽ(`Д´#)ノ

問題箇所を洗い出すべく、ヤケッパチの作戦に出ました。
すべての行間に

echo "test(任意の数字)" > out.log

これを入れ込んでって、out.logの出力がどこまで動いてるかを見て、停止原因となる箇所特定をしました。
まさかの配列変数初期化で停止
問題箇所はなんてこと無い1行でした。

array=()

シェルスクリプトではなんてことの無い、単に配列を初期化するだけの1行で停止していました。
もちろん、手動で実行すると動いていますから問題がある書き方ではありません。
declare -aという変数宣言コマンドも使ってみましたが動きません。
atコマンドが発するwarningの意味
atコマンドを実行すると良く見かけるのがコレ

warning: commands will be executed using /bin/sh

意味は /bin/shを使って実行されます です。
エラーでは無いためatコマンドは実行してくれるのですが、この警告がとても重要なのです。
Raspberry Pi オフィシャルOSである Raspbianは、標準のシェルとしてbashが使われています。
bashはとても高機能なので幅広く使われてるシェルプログラムなのですが、それも今のようなコンピュータが高性能になったおかげです。
それ以前は、性能の低いコンピュータに合わせたモノが使われていました。
atコマンドの警告表示に出ている/bin/shというのがまさにその使われていたshなのです。
Rasbianでこのshを見てみると

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4  1月 21  2014 /bin/sh -> dash

エイリアスでdashが呼ばれていました。
bashdash、1文字違いでヤヤコシイのですがどちらもシェルプログラムです。
両者同じものならわざわざ別に用意するワケがなく、もちろん別のシェルプログラム。
shとの互換性があるのがdashです。
互換性のないbash
動作しなかった配列変数を調べてみると、bashにはあってdash/shには無い機能の1つでした。
atコマンドが使うシェルプログラムの指定は出来ないのか調べてみましたが、それっぽい記述は見当たりません。
シェルスクリプト側を配列を使わない形に書き換えようとも考えたのですが、パッと良いアイディアが浮かびません。
そこで取った解決方法はコレ

#!/bin/sh
/bin/bash hogehoge.sh

bashを呼び出してシェルスクリプトを実行させる方法でした。
perl/ruby/python/php等のスクリプトも似たようにコマンドで呼び出して実行します。
bash向けシェルスクリプトもそれらと同様の方法で実行しました。
atコマンドがshのワケ
bashdash、1文字違いのシェルプログラムですが、その志しはまったく異なります。

dashPOSIX準拠のシェルプログラムです。
shの機能そのままにコンパクトで高速に動作する事を目的に作られています。
dashで走らせられるシェルスクリプトは実行速度の差はあってもshで走らせられる事ができる互換性のあるモノです。

bashshを拡張して高機能化したシェルプログラム。
後方互換のモノで、shのシェルスクリプトを実行可能にしつつ、さらに便利な機能も実装しているというもの。
ですから、bashの機能を使ってbash向けに作られたシェルスクリプトはshでは動かない可能性があります。

atコマンドもまたPOSIX準拠で作られており、そのためにshを標準シェルプログラムとして使っているのでしょう。
bashの未来
atコマンドのトラブルから学んだ今回のsh/dashbashの問題。
シェルスクリプト冒頭に書く

#!/bin/sh

コレもbash向けシェルスクリプトでは書くべきではないと言われている事は以前から知っていたのですが、今回の一件でその理由が良くわかりました。

bashは今回のRaspbianだけでなく、UbuntuやOS Xでも採用されてるシェルプログラムです。
WindowsもWindows Subsystem for Linuxという形で2016年夏リリース予定のWindows 10メジャーアップデート時に搭載されます。

これだけ見ると未来は明るいように見えますが、一方でPOSIX準拠が取れない現状。
POSIXモードというのも実装されていますが、それを前提として開発するならbashの存在価値は失われてしまいます。

心の片隅にとどめておき、どちらに転んでも良いシステム開発に心がけたいですね。