まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:mac

2017年6月の Raspbian のアップデートに合わせて PIXEL for PC(PC / Mac 用の Raspbian、わかりやすく言うと「パソコン版のラズベリーパイ」)も新しくなりました。以前のものは専用の Live CD だけが提供されていたのですが、現在のバージョンではハードディスク(仮想ディスク)へのインストールができるようになりました。「デスクトップ Linux 環境推進派」として見逃せないこの環境を早速ためしてみました:
2017073001


まず、今回導入したマシンは以下のようなスペックの仮想マシンです。おそらく実機でも問題ない、はず:
 ハイパーバイザー: KVM on CentOS 6
 仮想CPU: 1
 仮想メモリ: 1GB
 仮想ディスク: 10GB

まず最新の PIXEL for PC をダウンロードします。僕が今回使ったのはこの 2017/06/22 版の iso イメージです(2GB ほどあります):
http://downloads.raspberrypi.org/rpd_x86/images/rpd_x86-2017-06-23/2017-06-22-rpd-x86-jessie.iso


このイメージを使って仮想マシンを作成して起動します。実機の場合は iso を DVD に焼いて、その DVD をドライブに入れて起動することだと読み替えてください。なお(後でわかることですが)PIXEL for PC は Debian 8 ベースなので、仮想マシン作成時の OS の種類とバージョンは Debian 8 に相当するものを指定しています:
2017073002


なお作成時のオプションとして、(今回は)アーキテクチャに 64bit 版を選択しました。このあたりは実際に導入する環境に合わせてください:
2017073003


そんなこんなで ISO から起動します。最初に表示されるブートメニューでは "Graphical install" を選択しました:
2017073004


GUI インストーラーが起動します(この右上に "Debian 8" って表示されてますね)。最初にキーボードの種類を選択します。ここでは日本簿キーボードである "Japanese" を選択しました。選択後、 "Continue" で次の画面へ:
2017073001


ここで ISO をイメージを探して、そこから色々ロードして、・・・と少し待ちます:
2017073002


ここからが本格的なインストールオプションの指定になります。まずはインストール先ディスクとボリュームを指定します。僕はデフォルトの "use entire disk" を選択しましたが、LVM(論理ボリュームマネージャー)や暗号化 LVM を使う場合は適宜指定します。終わったら "Continue" :
2017073003


次にインストール先ディスクの選択を行います。この例ではディスクは1台しかないので、その1台のディスクを選択して "Continue" :
2017073004


選択したディスクのパーティショニングを指定します。ここでは(ディスクが大きくもないので)デフォルトの "All files in one partition"(全ファイルを1つのパーティションにコピー)を選択しています。そして "Continue":
2017073005


スワップ領域と合わせたパーティショニングの情報が表示されます。この内容で問題がなければ "Finish partitioning and write changes to disk" を選択して "Continue":
2017073006


ディスクに変更の書込みを行う直前の確認画面です。変更を行う場合は "Yes" を選択して "Continue":
2017073007


この後はパーティションのフォーマットが行われ・・・:
2017073008


インストール(ファイルコピー)が開始されます。環境にもよりますが、しばらく(数十分程度)待ちます:
2017073009


このような(GRUB がなんたら・・)画面になればファイルコピー完了はもうすぐです:
2017073001


ファイルコピーが済んだら最後に GRUB のインストールを行います。この画面では "Yes" を選択して "Continue" :
2017073002


GRUB のインストール先ディスクを指定します。今回は1つしかないので、その1つを選択して "Continue":
2017073003


最後のインストール作業が行われ・・・:
2017073004


この画面になったら再起動前にドライブに挿入している DVD(iso)を取り外します。iso の場合は仮想ドライブから iso ファイルを切断します。そして最後の "Continue" :
2017073005


最後に後処理が行われ、自動的に再起動がかかります:
2017073006


PIXEL の再起動がかかった直後はこんな画面になります:
2017073001


その後、おなじみのラズベリーアイコンが表示され・・・:
2017073002


PIXEL のデスクトップ画面が起動します! あのラズベリーパイではなく、(仮想)PC 上で Raspbian OS が起動しました。もちろん Raspbian OS 同様に利用できます:
2017073003


PIXEL でも標準で Scatch などは導入済みですぐに使い始めることができます。一方で Node-RED などは別途導入が必要なので、全く同じ構成というわけではなさそうです:
2017073004


もともと Debian っぽく使えていた Raspbian ですが、マシンの基本スペックが高いぶんだけ PIXEL の方が快適に感じるかもしれません。日本語化も含めたインストール作業後の諸設定はまた別途。


Linux ラブ!なプログラマーが陥った罠(おそらく多くの人が陥る罠)を紹介します。業務で Windows 機を使い、開発したアプリは Linux で上で動かす、という(よくある)環境で育ってきました。個人では Linux をデスクトップ用途でも使ってます。

なお、以下では全角文字で「¥(円)」と「\(バックスラッシュ)」を記述していますが、全て半角文字の時に起こる問題です。


そんな自分が Mac mini を支給され、Mac OS で Node.js の開発をしていた時です。「テキストファイルを読み取って、行ごとに分解(して何らかの処理を)する」という、珍しいとも思えない行分解プログラムをこんな感じで正規表現を使って書いてました:
const fs = require( 'fs' );
var text = fs.readFileSync( "xxxx.txt" );
var lines = text.split( /¥r¥n|¥r|¥n/ );     //. 改行コードがどうなっているのかわからないので、考えられる3通りで
console.log( "#lines = " + lines.length );  //. 試しに何行のデータだったのかを確認

これで改行コードが LF+CR でも LF でも CR でも、どのパターンのファイルでも split できるはず! と思っていたのですが、どんなファイルを試しても
  #lines = 1
と表示されてしまうのでした。"1" ということは1行、つまり分割ができておらず、元のデータがまるごと1つの配列要素になっただけ、ということ。

あれ? 正規表現の指定の仕方はこれじゃないかな?? ちょっと自信がなくなって、改行コードをオペレーティングシステムの設定値から取得するように変えてみたのですが、これでも結果は変わりません(そりゃそうだ、元のファイルの改行コードが OS の設定値になっている保証はない):
const fs = require( 'fs' );
const os = require( 'os' );
var text = fs.readFileSync( "xxxx.txt" );
//var lines = text.split( /¥r¥n|¥r|¥n/ );
var lines = text.split( os.EOL );           //. オペレーティングシステムの改行コードを指定
console.log( "#lines = " + lines.length );  //. 試しに何行のデータだったのかを確認

今まで普通にできていたことが急にできなくなって、ついに若年性ナントカの症状が・・とか不安になったのですが、このことを先人に相談したら一発で解決しました。
  「マックは¥(円マーク)と\(バックスラッシュ)のコードが違う」


え?、どういうこと?? 何言ってるのかよくわからないんですけど。。 

というわけで、歴史的にもややこしい経緯ごと振り返って紹介します。以下は表記上でわかりやすくするために全角で¥と\を書きますが、実際は半角文字だと思ってください。

昔々、国際規格においては(日本の通貨記号である)¥という文字はありませんでした。国際規格では\という文字がキー文字として定義されており、その文字コードは 0x5C でした。ここまでは何の問題もありません。

ここから話がややこしくなってくるのですが、この 0x5C というコードには国際規格的には\(バックスラッシュ)文字が定義された上で「各国が別の文字記号を割り当ててもよい」とされたのでした。そこで日本ではよく使われる¥(円)文字を割り当てました。つまり日本規格では¥というキー文字が定義されており、その文字コードはやはり 0x5C となりました。ここまでもあくまで割り当てルールの話なので、まあわからなくもないです。


そして時代は流れ、コンピュータが世の中に普及してくるにつれ、これまでの先進国だけでなく発展途上国でも使われるようになってきました。すると、これまでのコンピュータ文字体系の仕組みの中で新しい言語を更に追加して個別に扱うことに無理が生じてきました。そして「あらためて世界中の文字を単一体系で表現できるようにしよう」というユニコード(Unicode)の規格が生まれ、これが広まっていきました。このユニコードでは\(バックスラッシュ)と¥(円)も別の文字として区別して定義されました。基本的にはこの Unicode が現在も世界中で使われている規格です。


この新しい規格では¥と\がちゃんと区別されたのはいいのですが、これに移行するにあたってこれまでに日本語のファイルの中で "¥" として書かれた文字は、ユニコードでは "¥" とするべきなのか "/" とするべきなのか、という正解のない新しい問題が生じてしまいました。

この時に、内部的にシフト JIS というコードを採用していた当時のマイクロソフトの日本語版 Windows では Unicode 対応するにあたって「シフト JIS の日本語の¥は、Unicode では全て\として扱う。ただし表示では¥とする」という「見た目を変えない」ことを重視した解決策を取りました。つまり日本語版 Windows で¥のつもりで入力していたものは、実際には全て\でした。その表示上の見た目だけが(本来は異なる)¥になっていたのでした。見た目を変えない現実的な方法だったと思いますが、これがわかりにくい混乱の原因にもなったのでした。

一方、アップルの Mac OS X では元から Unicode 規格が採用されていました。つまり元から¥と\は区別されていました。日本語版のキーボード右上の¥キーを表示されるものは、あくまで¥であり、Option キーと一緒に¥キーを押して表示されるものが\でした(つまり Mac OS X では \ を出す方がややこしい)。


僕自身はこの段階でも「この違いって普通に使ってて問題にならないの?」と感じたのですが、実際はあまり大きな問題にはなっていないようです。マイクロソフトの「見た目を¥にして、内部的に\を使う」という解決策がいかに現実的なものだったかということだと思いますし、なにより自分がいままで¥のつもりで入力していた文字が実は(内部的には)\だった、ということを知りませんでした。知らなくてもどうにかなっていた、という事実の説得力がとても大きく感じられます。


これで¥と\をめぐる歴史的な問題は解決されました。めでたし、めでたし・・・ というわけにはいかない問題が残ってました。日本語でも英語でもない、プログラミング言語が関わった場合の話です。


多くのプログラミング言語においてはバックスラッシュはタブや改行などの目に見えない制御文字を定義する時に使うなど、特殊な意味を持つ記号とされています。この特殊記号が日本のコンピュータ規格では(バックスラッシュではなく、同じコードを共有する)¥とされていました。例えばタブ記号は国際規格的には "\t"(バックスラッシュ+t) ですが、同じものが日本では "¥t" と表示されていたのでした。見た目は異なりますが、元々\と¥は 0x5C という同じコードを共有していたので「要するに同じ文字」で、この段階では日本においては ¥ イコール \ と思っておけばまあ問題ない、とされていました。事実自分も「この2つは同じもので、使うシステムやフォントによって表示時の見た目が変わる」程度に理解していました。

ところが厳密に Unicode が使われるようになると話が変わってきます。例えば画面上で "¥t" と表示されている文字の内部コードは、タブを意味する「バックスラッシュ+t」のことなのか、「円記号+t(こちらは特別な意味のない2文字)」のことなのかが、使っている機種によって違ってくる、という事態が起こってしまいました。例えば Windows を使っている人が書いた "¥t" という文字列(正確には「画面上で "¥t" と表示されている文字列」)と、Mac OS を使っている人が書いた "¥t" という文字列は内部的には別のものになる、ということになります。


で、冒頭の話です。自分はもともと Windows を使っていて(Linux を使う時も Windows のターミナルアプリから使っていて)、その感覚で改行コードは「¥r¥nと¥rと¥nの3種類を考えればいい」と判断して、
var lines = text.split( /¥r¥n|¥r|¥n/ );  //. 本当は全部半角

という、改行制御を行う特殊記号を指定した正規表現の書き方にしました。でもこれは Mac OS では特殊記号を指定する時には¥ではなく\を使って、
var lines = text.split( /\r\n|\r|\n/ );  //. 本当は全部半角

のように書くのが正解だったのでした。要するに慣用的に「¥と\は一緒」と思ってしまうと、この落とし穴に気付くことができず、見て写したり、コピペしたりした結果動かなくなる、という症状に悩まされることになるのでした。

プログラミング以外にも、文字コードで一致を探す検索の機能などでも意識する必要があると思うのですが、裏を返すとプログラミングとかしない人にとっては特に¥と\の違いを意識する必要もなく Mac も Windows も使えているわけで、すごい歴史の一端を垣間見る経験でした。


IBM Bluemix の IoT アプリ開発でも重宝する IoT センサーシミュレーターサービスについての地味で大事な更新情報です:
https://quickstart.internetofthings.ibmcloud.com/iotsensor/


上記サイトにアクセスして表示される画面は「あるセンサーデバイスの温度、湿度、機器温度の状態をシミュレートしてネット上に自らの状態を知らせてくれる機能を持ったサイト」です。この辺りの詳細はこちらのエントリを参照してください:
Bluemix の Node-RED サービスで IoT アプリを作る

さて、このセンサーシミュレーターのサービスですが、いつの間にか少し進化していました。画面右上にはデバイス ID としてネット上での MAC アドレスが表示されているのですが、この表記からコロンが抜け、また初めからアルファベットが小文字になっています!
2015071701

(↑これまでのバージョンでは右上部分は 4F:A2:0A:09:A8:C8 と表示されていました)


これは結構大きなインパクトがあります。なんといっても「これで表示内容がデバイス ID としてがそのまま使えるようになった」のです。Node-RED エディタなどでデバイス ID を指定する際に単純に画面からコピペすればよくなりました(以前はコピペした値のコロンを取り除いて、アルファベット大文字を小文字に手で修正する必要がありました)。

Bluemix の IoT 関連サービス、ますます使いやすくなってます!


このページのトップヘ