Powerlevel9k * モリサワフォント

Zsh * Powerlevel9k を使っていて、なおかつモリサワパスポートユーザーである人なんて多分この世に数えるほどしかいないと思うので、需要は限りなく0に近い記事を書かせてもらうことにする。

Powerlevel9kで使われるU+F015(ホームマーク)やU+F17C(Linuxマーク)はPrivate Use(外字)領域であり、 文字として定義されていない。 そして、モリサワフォントはこの領域を使用しており、U+F015は「言信」という文字(実際は一文字)に割り当てられており、 モリサワフォントを導入するとAwesomeフォント(Nerd font)に優先されてしまうため、有効に機能せず、文字化けしてしまう。

解決方法は結構シンプルで、FontConfigで

のようにしてNerd fontをprependするだけである。

この問題のハマりポイントは、「Nerd fontのグリフを持っているCicaを指定したときにNerd fontグリフ部分を使ってもらえない」ことである。 だから、Cica一本に頼っていた場合はNerd Fontを別途導入する必要がある。

Zshでの連続的呼び出しに環境変数を使ってみる (Zshのガベージコレクション)

Zshは極めて強力なシェルだが、大規模プログラミングにおいて使われることは少ない。 だが、Orbital designにおいてはシェルスクリプトは強力な武器だ。できれば積極的に活用していきたい。 そうなると、Zshにおいて明らかでない、あるいは公知ではないことと付き合っていかなければならない。

単純に言えば今回は

のような処理を行うスクリプトを、invoke_workerがファイルを読み込むのではなく、事前に読み込んでおくことでワーカーの処理時間を短縮したいということだ。

のようにしたいということだ。

だが、問題は「これがメモリを食いつぶさないか」ということである。

意図と効果

普通のスクリプトの場合、この方法はほとんど効果をもたらさない。もしかしたらマイナスになるかもしれない。

そもそもこれらの情報が「単純にファイルとして読み込むだけ」の設計になっているところも工夫のなせる技なのだが、必ずしもそのようにできるわけではない。 特にクラスタ仕様になっているとファイルアクセスが遅いかもしれないし、その違いを吸収するためにさらに別の方法をとるかもしれないのだ。

ワーカーは起動数も多く、当然ながら処理としては重い。 逐次実行されるワーカー部分であまりその処理を担わせたくない。 特に設定のほうは起動される全てのワーカーにとって共通である。 これを環境変数にするメリットは大きい。

Linuxのfork(2)はコピーオンライトだ。 configは文字列であり、起動されるワーカーではその文字列をパースすることになるから、この$config環境変数が変更されることはない。 つまり、この環境変数は実体はひとつであり、常に同一の実体が参照される。コピーされることもないので速度が上がる。ディスクIOとメモリへのコピーが2回目以降省略できるのだ。

ただし、環境変数で渡す文字列は「システムコールがCライブラリである」ためにC文字列(の配列)であり、\000が含まれていると文字列がそこで終わってしまう。 私は勘違いと慎重さを欠いたことから赤っ恥をやらかしてしまった。

データのほうは、ほぼ単純に、ワーカー実行中に時間がかかる(かもしれない)データの取得を裏でやっておきたい、ということである。 これも環境変数にしてしまえばワーカーはリード時間をとられない。所要時間の総量は変わらないが、裏でやることで逐次実行部分に含めることを避けるということである。

問題と検証

だが、これは

というのが100万回実行されるということだ。 しかも、これはループのたびに異なる値になる。

もしZshにガベージコレクタがなければ100万件のデータを抱えてしまうことになり、これはメモリ消費量的にまずい。

というわけで、「Zshは変数を上書きしたらメモリを開放してくれる(ガベージコレクションしてくれる)のか?」という疑問を解き明かす必要ができた。

この調査は割と簡単で

とし、

のようにしてメモリ消費量を監視すれば良い。

ちなみに、100Mを指定しているが、/dev/urandomは一度に読めるのは32MiBまでである。

80340
215640
80332
80332
80348
43344
80340
80340
80332
80332
215636
80340
80332

だいたい2倍程度と見ていいと思うのだが、ときどき3.5倍程度まで増加する。 ただ、だいたい2倍ということはかなり迅速にメモリを回収してくれている印象だ。

しかし、実際のワーカーはこんなに長時間実行はしないので、実際のワーカーの実行時間に近い感じにしてみよう。

108932
80340
195300
80340
215628
80340
211472
111616
80332
178644
43344
215644

回収しきれないタイミングが増えてメモリ使用量にばらつきは生じているが、回収ペースを上回ってメモリ消費量が果てしなく増えていくようなことはないようだ。

結論

  • Zshにはガベージコレクタがある
  • Zshでパラメータを上書きすると、ローカル変数か環境変数かによらず迅速にメモリは解放される
  • IOコストが高いなどで逐次的に実行するコストを削減したい場合、コントローラで環境変数にする作戦はなかなか有効

追加の注意点

フルスケールするように設計されているワーカーの場合、CPUコア数を使い切るだけワーカーを起動していると、結果的に裏で色々するためのコンテキストスイッチコストが高くついて全体では遅くなる可能性もある。 というか、ワーカーの実行がそれほど時間のかからないものであるならばwaitの時間は短くなり、waitの時間が短くなるほどスケール阻害要素としては大きくなる。

エンジニア&ワナビーに贈る名著7選

はじめに

昔Twitterで似たようなタグがあったような気がするのだけど、 私はコンピュータ関連書籍(雑誌込み)には300万円くらいはつぎ込んでいるので、その中で「これは色褪せない、他にはない、素晴らしい!!」と思ったものを挙げたい。

私が今まで読んできた中でボロボロになるまで読んだ本たちだから、だいたいの本は古く、そして絶版・入手困難になってしまっている。

このほかにも見どころがあって、色褪せない本というのはあるのだが、今回は「名著」と言い切れるような必読書のみに絞って挙げてみた。

ハッカーズ大辞典

いわゆる「おもしろ用語集」のような本。

用語自体が技術的知識になる、という側面は少ないのだけれど、 昔のハッカーたちがどんな棋風で、どんな出来事で、どんなふうに接し、振る舞ってきたのかがわかる「文化本」という意味合いが大変に強い。 そして、ハッカーマインドを理解するにもこの本は欠かせない。

ここに登場する語のほとんどは現役ではなく、実際に使われることは多くはない。 だが、ハッカーは大概、この本のことは知っているし、ここに登場する用語や背景のことは知っている。 これらのことは元ネタである “Jargonfile” で呼ぶことが多いが、実際にはこの和訳本のことを示していることがほとんどである。 このJargonfileのオリジナルはインターネット上で読むことができるが、和訳も大変イケているので、ぜひ翻訳本をお勧めしたい。

だが、残念ながらこの本は絶版である。 改装版が出ていることを知らなくて、私は今でも探しているくらいだ。 (私は翻訳初版しか持っていない)

インターネットの起源

インターネットはどのように誕生し、どのような苦労があったのか、 そのときどのような信念があったのか、それを窺い知ることができる名著。 翻訳が少し雑なのが気になるが、貴重な当事者の証言である。

インターネット陰謀論を吐きたがる人には一度は読ませたい本だ。

こちらも絶版プレミアだが、Kindle版があるのが救い。

プログラミングPerl

「ラクダ本」といえばこの本。 Perlを学ぶ人だけでなく、プログラミングを学ぶ全ての人にとって一読の価値のある名著であり、特に正規表現を理解するには (オライリーの「正規表現」以上に)この本の助けが必要となるだろう。

PerlはCほど難解ではないが、隠しきれない低レベル感がある。 ひとつひとつの概念を丁寧に解説してくれるので、プログラミングについて理解する良い下地になる。 「書いてあることをそのまま実行する」ことに頭が行くタイプの人には向いていないだろうが、理解して地力を高めていくということが分かる人には地力育成法としてかなり良い本だと思う。

上下巻なのだが、VOLUME2はリファレンスであるため、「なくてもよい」感が強く、VOLUME2のほうは事実上の絶版。 VOLUME2の巻末の用語集は結構おもしろいのだが。

Perlクックブック 第2版 VOLUME1

Perlを実用的に活用するための本、なのだが、クックブックなので基本的にはテクニック集だと思えばいい。 だったらわざわざ挙げるほどではない、と思うかもしれないが、割とクックブックって良いものが少なくて、推挙できるのはこれぐらいのものだ。

このクックブックにはふたつの面がある。

ひとつは、ラクダ本で学ぶことができる基礎によって理解を深めても、実際になにかを実現しようと思ったときにどうすればそれが実現できるのかということを教えてくれる教科書としてだ。

そして、もうひとつはここに書かれていることを理解できるかどうかが、プログラミングに対する理解度をはかるものになるということだ。 小さな課題をテクニックを駆使して解決しているため、それによって解決できることはわかるのだが、レベルが十分に上がっていないとなぜそれによって解決できるのかがわからない。 読み物として読んだときにするっと理解できるようになったとき、自分のレベルが向上したことを実感できるだろう。

VOLUME2はPerlに特化した部分が多いので、VOLUME2はあまり必要ないかもしれない。 いずれにせよ絶版本で、入手は難しい。

Hacking:美しき策謀 第2版 ――脆弱性攻撃の理論と実際

誤解してほしくないのは、これによって攻撃ができるようになるような類の本ではない。 この本はそもそもかなり小さくて薄い本なので、そこまで充実の中身はないのだ。

だが、多くの人が「なんとなく言葉と、用語集の説明文程度で知っている」脆弱性攻撃の中身を、簡潔かつ的確に教えてくれる。 この知識は脆弱性攻撃のみに有効なわけではなく、コンピュータの低レイヤーを理解する補助教材としてかなり有効だ。 低レイヤーが苦手な私はこの本に随分助けられた。

ここで扱っている内容は非常に難易度が高く、実際に学ぼうとするとかなり困難を伴う。 もちろん、この本の記述範囲で理解できるはずもないのだが、なんとなく理解し、興味をもつには良いだろう。

新The UNIX Super Text 上 改定増補版,

私がLinuxをちゃんと学び直すときに使った教科書だ。

2003年刊行なのだが、内容は1997年のオリジナルからほとんど変わっていない。 結果的に、2003年時点でも大部分が「そのままは使えない」内容となっており、現在はそのまま使える知識などないに等しい。

だが、「何が基礎で、何が今につながり、それをどうすれば活用できるのか」ということを考えながら読むと、基礎を学ぶには最適なものになる。

実際、Mimir YokohamaのLinux基礎やコンピュータ基礎のカリキュラムづくりは、この本での内容をかなり参考にしている。 実際のところそのまま使える部分はほとんどなく、現代の技術に置換えただけで説明が完了するものもないため、流用できる内容はほとんどないのだが、どのようなことで構成し、何に触れるか、基礎としてどのようなことを学ぶことが地力の育成につながるか、ということを考える上で大変参考にさせていただいている。

この本の残念なところは、著者に一名、ちょっといい加減なことを偏見込みで書いている人がいることだろうか。

まつもとゆきひろ コードの世界‾スーパー・プログラマになる14の思考法

Ruby設計者のまつもとゆきひろさんの本。シリーズとして「コードの未来」「言語のしくみ」という本もあるのだけど、やはり名著といえばこの「コードの世界」だと思う。

技術書というよりは、文字通り「コードの世界」を紹介した本であり、特に難しいと感じる人の多いプログラミング言語にとっての文字コードの「内部コード」と「外部コード」の違い、正規表現エンジンの挙動と違い、並列実行などについてinsiderの視点で解説されており、楽しく読める上に読んでいるとプログラミングに関する理解も深まる。

「コードの未来」も併せて読みたい良書だが、こちらは技術を紹介する色合いが強いため、必読とまで勧められる感じではない。だが、お勧めではある。

WindowsがUTF-8(BOMなし) を標準に

長かった…

Windows 10 Insider Preview Build 18298(19H1) でメモ帳がUTF-8(BOMなし)に対応し、これをデフォルトとした。

わかる人はこれだけで十分だろうから、わからない人にむけて解説しよう。

日本語WindowsはシステムロケールとしてMSCP932という文字エンコーディングを採用していた。 この文字エンコーディングはJIS X0201及びJIS X0208文字集合を表現するShift JIS文字エンコーディングをベースに、NECとIBMがShift JISがX0208のテーブル外を指しているポイントに独自に文字を定義した。

これはJIS X0208を拡張しているわけではなく、Shift JISがJIS X0208に対して直接マップされたものであることからShift JISがJIS X0208のテーブルを指しているよりも後側、2バイトで表現できる範囲は未定義であり、ここを昔からの慣例通り「外字」として好き勝手に使用していた。 同様にNECとIBMが勝手に定義したものなのだが、広く使われればあたかも規格であるかのように扱うことができる。 Microsoftはそれを規格にしたCP932という文字集合と文字エンコーディングを採用したわけである。 事実、CP932とShift JIS(JIS X0208)には一部同一ポイントで異なる文字がある。

だが、文字集合や文字エンコーディングは合意ありきのものであり、「独自のもの」というのはそのOSに閉じ込められた文化になってしまう。 基本的にはMicrosoftはこれを「Shift JIS」であると呼んだ。それどころか、「ANSIである」とすら言った。

ANSIというのは国国家規格協会のことであり、ANSI Character EndingといったらANSIが決めたASCII(US-ASCII)のことを指すのだが、Windowsで「ANSI Code Page」といったらMSCPと呼ばれる、Microsoft独自の文字集合兼文字エンコーディングを指している。これは、「システムローカル」のような意味で、気軽に勝手に名乗られたANSIはキレていいと思う。

当時、WindowsはMSCP932(Shift JISとは微妙に互換性がない)にCRLF改行文字、MacはMacでNECの独自のShift JIS拡張を取り込んでさらに拡張したMacJapaneseなる文字集合兼文字エンコーディングを採用し、CR改行文字、Unix系はEUC-JP文字エンコーディングにLF改行と世は大戦争である。

ちなみに、日本語WindowsにおけるCP932は

  • Windows-31J
  • MS932
  • CP932
  • MS漢字コード
  • MSCP932
  • OEMコードページ932
  • Shift JIS

という呼び方があり、勘違いも含めてそれぞれ意味は違う。地獄だ。 ところが、「Windows-31Jは互換性問題解消のために生まれた」ところがまた地獄だ。

ここで話はさらに複雑になる。Windows NTはまだ登場間もない文字集合Unicodeに対するUTF-16LEをシステムエンコーディングとして採用し、新しいファイルシステムであるNTFSの文字表現もFATと違いシステムローカルのMSCPではなく、UTF-16LEを使用するようになった。 このときはまだサロゲートペアが導入される前のお話である。当時は、65536文字でこの世に存在する全ての文字が表現できると(少なくともアメリカ人には)信じられていたし、それが幻想だと気づいていなかったのだ。だから、65536文字を表現できるUTF-16こそが最も美しい文字エンコーディングだと(少なくともアメリカ人には)信じられていた。

だが、それがまた悲劇を生む。この世界の文字は65536文字では収まらなかったし、サロゲートペアは日常的に使うものだったし、UTF-16に十分なメリットはなかった。

現在主流となっているUTF-8が拒まれた理由は可変長文字エンコーディングであったことだ。 現在UTF-8は1文字を表す長さは1バイトから6バイトまである。 これに対してUTF-16は単位が2バイトであり、「2バイトが1文字」として扱える。これは、「ファイルを途中へシークしても文字の区切りはどこか予め知ることができる」というメリットがあり、また、文字の長さを知る必要がないということもある。

だが、現実はそうはいかなかった。サロゲートペアによってUTF-16も事実上可変長文字エンコーディングになってしまったのだ。 頑なにUTF-16のメリットが損なわれたことを認めない人は今でもいるけれど、今世の中は「UTF-16にしてもどうせ可変長なのだし、それだったらUTF-8がいい」という意見が大勢をしめている。

UTF-8はバイト列であり、「1バイトずつ読んで処理する」ということになっている。これは、エンディアンが関係ないというポイントがある。 エンディアンは「ビットの並び」ではなく、「単位中のバイトの並び」であることに注意してほしい。 例えば2バイト単位であれば、2バイトのうち「上位ビットは先にくるのか後に来るのか」という問題が発生するのだ。 なんでこんな問題が発生するのかというのは、様々なケースを示さないとならないので、ちょっとここではやめておく。要は「どの時点でコンピュータの事情にあわせてひっくり返すか」のタイミングが違う。

ところが、可変長の場合はそうはならない。長さがわからないので複数バイトを一気読みすること自体できないのだ。 なので、先頭1バイトを読んでこれを第1バイトとし、ここで完結していなかったら次の1バイトを読んで第2バイトとする、というような振舞いになる。だから、解釈する方法はひとつしかない。

世の中はUTF-8が標準になってもWindowsとしてはそうやすやすとUTF-16LEをやめますというわけにはいかなかったし、頑なにUTF-16LEを守り続けてきた。Windows 10になって以降は、さすがにMicrosoftとしても危機感を持ち始めてUTF-8に対応しつつある。

だが、Microsoftはまた過ちを重ねてしまった。 ひとつは、UTF-16LEを「Unicode」と呼び、UTF-8を「UTF-8」と呼んでしまっていること。そして、MicrosoftのUTF-8にはBOMがついていることだ。

BOMはバイト列の並びを表すためにつける印である。 これがどのようなバイト列で並んでいるのかということに基づいてLEなのかBEなのかを判断できる。

だが、先程も言ったように、UTF-8は「並べる順番」というものが存在しない。にもかかわらずBOMをつけるのは無意味であるといっていい。 しかし、Windowsの場合、これを「UTF-8の識別方法」として使っている。「先頭のバイト並びがこうだったらUTF-8」という判定方法をとっているのだ。 公式にはUTF-8としてはBOMは「容認するけど非推奨」である。

にもかかわらずWindowsは常にUTF-8にBOMをつけてきたし、BOMなしUTF-8という選択肢を与えてこなかった。 やむなくBOMなしUTF-8を認める場合でも「UTF-8N」なる名称をつけてこちらが特殊なものであるかのようにみせかけてきた。 BOMなしUTF-8はWindowsでは文字化けフラグだが、どちらかといえばBOMつきUTF-8のほうがトラブルの元である。

これに加えてBOMありUTF-8の問題点として、UTF-8は1バイトで表現できる範囲は0x7FまでASCIIと同一であり、ASCIIのみで表現されたUTF-8文字列はASCIIとして扱えるというメリットがあるのだが、BOMがつくことでこのメリットは消滅する。

Windowsが拡張されたShift JISを採用してきたことも、システムにUTF-16LEを採用したことも、歴史的経緯を考えれば妥当と言えるのだが、UTF-8にBOMをつけたことだけは「邪悪な行い」でしかなかったのだ。 そして、そんなことをするのは基本的にWindowsだけであり、誰も歓迎しなかったのである。

だから「せっかく標準のUTF-8にしたのに、変なものを仕込んで標準を破壊し面倒な処理を強要するWindows滅ぶべし」だったのだが、ようやくMicrosoftもみんなと協力する気になった、というわけだ。

本当に長かった。多分、Officeもそのうち対応してくれることだろう。

ConoHaとArch LinuxではじめるLinux

ごあいさつ

Hi, there! はるかみです。

この記事はConoha Advent Calendar 2018の7日目として書かれたものだよ。 いままでChienomiを見たことある人もない人も楽しんでいってね。

基本的にChienomiはedgeな記事を書くことが多いけれど、Advent Calendarのときだけは初心者向けの記事を書いたりしているんだ。 Chienomiでは最近で最もアツかったのは高EQ AIに関する記事だよ!

本当はConoHa WINGに関する記事を書こうかと思ったけど、Advent Calendarで書くようなものじゃないと思ったんだ。 考えていたものは検証に5, 6日必要だとわかったから協賛でもしてもらわないと無理だとわかったんだよ。

それにConoHa WINGでConoHa Advent Calendarのハードルも下がって、今年はWINGに関する記事がたくさん載るだろうからね。え?毒が少ないって?さすがに同じAdvent Calendarの記事に毒を吐くのは来年にとっておくよ。

あなたはLinuxを使っているだろうか。

最近はLinuxというとドヤりツールになっていたり、あるいはミーハーなものになっていたりもする。 あとは、仕事のための箔付けだろうか。

それはLinuxのなんたるかがわかっていない…と思うのだが、ここではそんな話はおいて、とりあえずLinuxを触ってみたいという人のお手伝いをしよう。

この記事にかかれていることはかなりの部分、過去の記事や他で書いたことと重複してしまうのだが、Advent Calendarの記事ということでご容赦願いたい。

今回はLinuxを全く使ったことのないWindowser向けにエクスプレスで進めていく。 スキル不足が直接に迷惑になるサーバー構築ではなく、またデスクトップ用途でもない。

なお、Linuxそのものを体験して評したいのならばメインマシンにLinuxをインストールするよりない。 LinuxのUXはWindowsのそれよりはるかに優れているが、それはさすがにVPSでわかるようなものではない。

また、副次的に性能の低いコンピュータを使っている人の場合、月1000円から2000円程度で強力なコンピュータにオフロードできる、という面でも話していこうと思う。

SSHを用意する

Windows 10では2017 Fall Creator UpdateからOpenSSHが標準採用になっている。ちなみに、2018 Aprilではサーバーも入っている。 とりあえずまだWindows 10ですらない、という人のことはあまり考えたくないので、そこから話を進めよう。

まずはcmdを検索、あるいは“プログラムを指定して実行”からcmd

Windowsでcmd.exeを探す

ssh -VでOpenSSHを確認。

C:\Users\Harukamy>ssh -V
OpenSSH_for_Windows_7.6p1, LibreSSL 2.6.4

ssh-keygenで鍵を作成する。 Microsoftが提供するWindowsアプリでありながらUnixスタイルとWindowsスタイルが混在してとてもわかりづらいことになる。 OpenSSHが使うディレクトリは相変わらず%HOME%\.sshなのだが、Explorerでドットファイルが作れないのでコマンドライン上で行う。

>mkdir .ssh

その上でSSH鍵を生成する。

>ssh-keygen -f .ssh/conoha_rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in .ssh/conoha_rsa.
Your public key has been saved on .ssh/conoha_rsa.pub.
The key fingerprint is
SGA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX harukamy@HACKMAN
the key's randomart image is:
+---[RSA 2048]----+
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
+---[RSA 2048]----+

このパスフレーズは秘密鍵を暗号化しておき、使用するときに解除して使用するためのパスフレーズである。 システムが十分に安全かつ強固に保護され、運用されているのであれば(物理的に盗まれることも、ネットワークごしに盗まれることも、ディスクをコピーされたとしても使われることも)ないのであればパスフレーズはなくても構わないし、まず考えられない程度に強固なのであればほどほどに強固なパスフレーズでも構わないだろう。

これでホームディレクトリ以下.ssh/conoha_rsa(秘密鍵)と.ssh/conoha_rsa.pub(公開鍵)のペアが作成される。

Explorerではとてもホームディレクトリにアクセスしづらいので、そこをなんとかしておこう。 ExplorerでC:\Users\ユーザー名に移動し、“クイックアクセス”を右クリックして“現在のフォルダーをクイック アクセスにピン留め”を選択する。

あと、適切なエディタがないのも困るので、インストールしておくといい。 無難なのはみんな大好きNotepad++。

ConoHaでサーバーを立てる

ConoHaでの契約については公式のページをみてほしい。

それではConoHaにログインし、“サーバー追加”からサーバーを追加しよう。 練習用なら512MBで良いだろうし、パフォーマンスオフロードを期待するなら1GB以上にしよう。 OSはもちろん、Arch Linuxである。

ConohaでArch Linuxインスタンスを立てる

Rootパスワードは本当に強固なものにすること。 ここはあまり心配のない部分だが、それでも24文字以上くらいにはして欲しいところだ。

オプションを開き、接続許可ポートを設定する。 IPv4/IPv6ともSSHのみを許可するように設定する。 IPv6のない環境からアクセスするのであればIPv4のみでも構わないし、IPv6でのアクセスが確実な接続形式をとっているのならIPv6のみのほうが良い。

ConohaでポートとSSHキーの設定

そしてSSH Keyセクションは “キーを新規作成” を選択し、“登録方法”に“インポート”を選択する。 そして“パブリックキー”のところに、作成した~/.ssh/conoha_rsa.pub (.pubファイル!!!)の内容をコピペする。

この時点で鍵登録しておくとSSHのパスワード認証が無効化された状態でインスタンスが立つので安全な状態になる。

インスタンスを作成し、起動したら、ConoHaのサーバー一覧からサーバーを開くと“VPS設定”からI逆引きホスト名を知ることができる。

それでは例えばここがv0-0-0-0.a00a.tyo0.static.cnode.ioだと仮定しよう。

SSHでログインする

ではいよいよWindowsに戻ってログインしよう。 OpenSSHの-iオプションに秘密鍵を指定する。引数はSSHのホストだが、その前にユーザーが必要だ。

>ssh -i .ssh/conoha_rsa root@v0-0-0-0.a00a.tyo0.static.cnode.io

ログインできたらexitして一旦SSHを抜ける

# exit

もう少し楽にログインできるように設定をしておこう。 .sshディレクトリにconfigというテキストファイルを作成する。拡張子はない。 UTF-8+LFで編集してくれるエディタを使うのが良いかもしれない。

このファイルは次のような感じだ。

Host conoha-root
  HostName v0-0-0-0.a00a.tyo0.static.cnode.io
  Port 22
  User root
  IdentityFile .ssh\conoha_rsa

これで

>ssh conoha-root

とするだけでログインできるようになる。

OpenSSHが使えない場合

TeraTermを使う方法が公式で紹介されている。

TeraTermの使い方公開鍵の使い方が紹介されている。

ユーザーを作成する

Windowsでは歴史的経緯から曖昧だが、rootユーザーというのは全権を持つ「神」であり、普段使うべきではない。 それどころか、rootのシェルプロセスがあるだけでも望ましくないくらいだ。

Archはインストール時にユーザーを作成しない。自ら作成する必要がある。

ではログインして作業しよう。 ユーザー作成コマンドはuseraddだが、オプションとしては-U(ユーザープライマリグループを作成する), -G(グループを指定する), -m(ホームディレクトリを作成する)を使用する。 このユーザーは管理ユーザーとなるのでwheelグループに加えておこう。

# useradd -U -G users,wheel -m conohachan

ユーザーのパスワードを設定する。とても強固なものが良い。

# passwd conohachan

ユーザー用の鍵を登録しよう。ここではOpenSSHを前提に進める。 Windowsでもうひとつcmdを立ち上げ、先程と同じ要領でキーを作る。

>ssh-keygen -f .ssh/conoha-user_rsa

configを追加する。今度は鍵とユーザーが異なる。

Host conoha
  HostName v0-0-0-0.a00a.tyo0.static.cnode.io
  Port 22
  User conohachan
  IdentityFile .ssh\conoha-user_rsa

鍵をアップロードする。まだrootでしかログインできないので、rootで送る。

>scp .ssh/conoha-user_rsa.pub conoha-root:.

これでConoHaのrootホームディレクトリにコピーされるので、これをSSHに戻ってセットアップする。 まずはユーザーの.sshディレクトリを作る

# mkdir ~conohachan/.ssh

そして、authorized_keysというファイルとして配置する。

# mv conoha-user_rsa.pub ~conohachan/.ssh/authorized_keys

このままだとrootユーザー所有ファイルになってしまうので、直しておく。

# chown -R conohachan:conohachan ~conohachan

.sshディレクトリはオーナーのみアクセス可能であることが求められるため、パーミッションを修正する。

# chmod 700 ~conohachan/.ssh

これでユーザーとしてログイン可能になったはずだ。

>ssh conoha

初期設定

まだrootのセッションも閉じないでおこう。 この状態では管理作業ができるのはrootだけなので、conohachanにも許すようにしたいところだ。

/etc/sudoersというファイルを編集するのだが、これは直接編集してはならない。 visudoというコマンドを使う。エディタにVIが入っていないのでエディタも指定してあげる必要がある。

# EDITOR=nano visudo

下の方にこんな行がある。

# %wheel ALL=(ALL) ALL

このコメントアウトを外しておく。次のように。

%wheel ALL=(ALL) ALL

オーケー。Ctrl+Oして保存し、Ctrl+Xで終了しよう。

ConoHaでは最近、script側でアップデートするようなので不要に思えるけど、一応アップデートしよう。この作業は定期的にしなければならない。

# pacman -Syu

カーネルパッケージ(linuxというパッケージ)が更新対象に含まれていた場合は再起動する。SSHのセッションは切られる。

# reboot

もう少し使いやすく…

とりあえずここからはLinuxを長年使っている身として「それなりに使いやすい環境を整える」ところをやっておきたいと思う。 特にArch Linuxはミニマルなので足りないと感じるものは色々あるだろう。

パッケージを揃える

まずはユーザーログインする。

>ssh conoha
Enter passphrase for key 'C:\Users\harukamy\.ssh\conoha-user_rsa':

$

ちょっとrootでの作業が続くのでrootになる。

$ sudo bash -l
[sudo] password for conohachan: 
# 

サーバーなら必要ないのだけど、まずはユーザーで電源切ったり再起動したりできるようにしておこう。pacmanはArch Linuxのパッケージ管理ソフトウェアであり、ソフトウェアをインストールしたりアンインストールしたりアップグレードしたりできる。

# pacman -S polkit

これでsystemctl poweroffsystemctl rebootがユーザーでできるようになる。

VI, vim, Zshはなくてはならないソフトウェアだ。あと、ターミナルデュプレクサも欲しいのでtmuxも入れておこう。 Zshはgrml-zsh-configパッケージをインストールするとすごく使いやすくなる。 あと、このあとyayを入れる関係でgoとgitも入れておく。

# pacman -S vi vim vim-plugins zsh grml-zsh-config tmux go git

いい感じになってきた。ここで一旦rootを抜け、tmuxを起動する。

# exit
$ tmux

tmuxはプレフィックスキーを押したあとになにかキーを押すとtmuxに対する指示になるようになっている。 デフォルトのプレフィックスキーはCtrl+bで、?を入力することによりキーバインドの一覧が表示される。

とりあえずcが新しいウィンドウを作成するコマンドなので、Ctrl+b Ctrl+cと入力しよう。

これでわかりにくいがふたつのウィンドウができた。nコマンドによりこのウィンドウを行き来できる。

pacmanが扱うことができるのはArch Linuxの公式パッケージだけだ。 AURという、非公式の(しかし、運営自体は公式に行われている)パッケージも扱いたいので、yayというソフトウェアをインストールする。 手順は

  1. Gitを使ってyayのリポジトリをコピー
  2. yayディレクトリに移動
  3. makepkgでパッケージを作成
  4. pacmanで作成したパッケージをインストール
$ git clone 'https://aur.archlinux.org/yay.git'
$ cd yay
$ makepkg
$ sudo pacman -U *.pkg.tar.xz

これでAURのパッケージもインストールすることができる。 もし、yayに不満ならばついでにもうひとつのAURヘルパーであるtrizenもインストールしておこう。pacmanと違い、AURヘルパーはユーザーとして実行する。

$ yay -S trizen

yayやTrizenは公式のパッケージも扱うことができる。

見やすく、使いやすく

まずはすごく簡単な話として、Bashなど投げ捨ててZshにしよう。 Bashなんてゴミだ。

まずは.zshrcを作っておく。

$ touch .zshrc

オーケー。Zshにしよう。

$ chsh
Changing shell for conohachan.
Password: 
New shell [/bin/bash]
> /bin/zsh

chshはログインシェルを変更するだけなので、今のシェルは変更されない。 一刻も早くBashやZshに変えたいので、Zshでログインしよう。

$ zsh -l
%

Poifect! grml-zsh-configをインストールしているのでとても快適に仕上がっているはずだ。 とりあえず途中でわからなくなったら、わかるところまで打ってからTAB連打で切り抜けられる。オプションやオプション引数なんかもだ。 あと、f/b/b<TAB>foo/bar/bazに展開する、なんてこともできるようになる。

さらにZshを強化して、Zshから離れられない体にしてやろう。

$ yay -S zsh-completions zsh-syntax-highlighting

Syntax Highlightを使用するため、.zshrcに次のような記述を行う。 vimが使えるならvimを使えばいいし、ダメならnanoでもいい。

grml-zsh-configはヒストリを辿ったときに「既に第一ワードを入力している場合は第一ワードを確定として、途中の場合は第一ワードの検索開始時カーソル位置までを確定として辿り、カーソルは末尾に移動する」という挙動になっているのだが、「常にカーソル位置までを確定として履歴を辿る」という機能も欲しいのではないだろうか。 というわけで、PgUp/PgDownでそのような検索ができるように.zshrcを追記する。

うーん、beautiful!

さて、ここからはちょっと複雑なことをする。 わかりやすく美しいZshプロンプトのPowerlevel9kを使いたいと思うのだが、これはWindowsだとひと手間ふた手間ある感じだ。

とりあえずインストールだけはしておこう。

$ sudo pacman -S zsh-theme-powerlevel9k

ここからは一旦ログアウトして(各シェルのログアウトしたあとSSHからログアウトするのを忘れずに)Windowsだ。まずはGit for Windowsをインストールする。

これで様々な問題を解消できるようになる。別にMSYS2を入れてもらっても構わないのだが、Git Bashが各種設定を済ませてあるので話が早い。

そして、次にCicaフォントをインストールする。 完全なPowerlineグリフを持っているので話が一番てっとりばやい。このフォント、グリフが豊富で見やすく、制限された状況で本当に便利だ。

で、Git Bashを起動して、右クリックからのOptionsで、フォントをCicaにする。ここまでやっておかないと後で困る。 それではGit Bashからログインしてみよう。

$ ssh conoha

通常Git Bashでも.exeは省略できないのだが、sshはGit Bash側で定義されており、省略できる。

minttyになったことでだいぶ見やすくなったのではないだろうか。Cicaフォントだし。 で、powerlevel9kなのだけど、とりあえず私がサーバーで使っている設定を晒そう。

これはVIモードで使うことを前提にしているので、一般化すると次のような感じか。

で、powerlevel9kなのだけど、とりあえず私がサーバーで使っている設定を晒そう。

grml-zsh-configを使っている関係で先にprompt offするのは必須。 FOREGROUNDとBACKGROUNDの色はお好みで、という感じだ。 Zsh上で(つまり、ログインしたConoha上で)

% for i in {000..255}; do print -P "$i %K{$i}     %k"; done

とやれば、番号ごとにどんな色か把握できる。 もちろん、もっと好みに設定を変更しても構わないだろう。

これも.zshrcに記述する。

この設定は作業中のミスをなくすために行っているもので、実のところ私は普段はPowerlevel9kを使っていない。 だが、SSHから入ったときだけPowerlevel9kになるようにしており、ホストごとに色を変えてある。このことにより、「ローカルホストかリモートホストかを間違える」事故を防止している。

実際、普段はgrmlデフォルト

このホストにSSHで入るとこうなる。

フォントが設定されていないcmd.exeから入ると表示が乱れている。右側のウィジットが次行に表示されているので使えないこともないが…

Git Bashなら正しく表示される。

Powerlevel9kの利用は好みの問題だと思うけれど、Git Bash + Cicaという組み合わせはやって損がないのではないだろうか。

Powerlevel9kの利用は好みの問題だと思うけれど、Git Bash + Cicaという組み合わせはやって損がないのではないだろうか。

自動アップグレード

とりあえず毎日朝6時にアップグレードするようにしてみよう。 Arch LinuxのinitであるSystemdというものを利用する。SystemdにはSystemdタイマーというジョブスケジューラがあるので、これを使うのだが、説明はとても難しいのでとりあえず例示にとどめよう。

rootとして/etc/systemd/update.serviceを作成する。

% sudo nano /etc/systemd/update.service

続いて/etc/systemd/update.timerを作成する。

% sudo nano /etc/systemd/update.timer

時は来たれり

バッチリだ。ここまで来れば、 サービスや他者に迷惑をかけない範囲であれば 君が学んだことを存分に発揮できる場が出来上がったはずだ。

例えばvimを練習したいのなら

% vim vim-training-file

とかやればいいし、Pythonでプログラムを書きたいなら

% vim myfirst.py

とかやればいい。

Linuxについて教えると話は無限に長くなるし、そもそもここまでの一連の作業でそれなりにLinuxに慣れる要素もあったので、Advent Calendarの記事としてはこれくらいで良いではないかと思っている。 この記事のソースファイルはこの行が606行目だし。

というわけで、世の中の人がちょっとでもLinuxに、そしてコンピュータに関心を持ってくれれば幸いだ。 ついでに、こんなふうに簡単にサーバーを立てて、練習やアウトソースにも使えるConoHaは素晴らしいサービスです!(おべっか)

Linuxについての突っ込んだ話はこのChienomiでしているから、関心がある人はぜひチェックして欲しい。 コンピュータやLinuxについて学びたい、教えて欲しいという人はぜひMimir Yokohamaへどうぞ。

それでは今年もこのへんで。はるかみ☆でした♪

蓄積は裏切らない

かつては不安と共に

ここのところかなり難しい…というか、ストレンジなチャレンジが続いていた。 いや、今年は結構その色合いが強かったかもしれない。勝手知ったることよりは未知のことが多かった。

基本的に私は自信家ではなく、分析に寄っているので、評価できない事柄というのは基本的に自信がない、つまりは不安である。

だが、さすがに私はコンピュータ歴も長いし、そのほとんどは学習や非知的生産ではなく道を拓くことに費やしてきた。 なにかをしようとしてつまずきなく成果が出るようになったのはここ2年くらいだと思う。それ以前には相当に案を練ってうまくいく確信があったのに、実際にやってみるとそもそも理屈通りに動かないというようなことで頓挫することがよくあった。

しかし、無駄だとは思わなかった。その過程で被害は大きかったが1、うまくいかないことをネガティブには捉えていなかった。 むしろ、昔とは違う、誰も経験のしたことのないトラブルでも今私は立ち向かえているということに喜びを覚えてすらいた。 不十分な知識と過剰な評価に不安しかなかった昔とは大違いだ、まさに私は今望んだ結果の上に立って戦っていると思えていた。

戦えるようになって、躓きながら前進する

それはひとつの結実だったけれど、ようやく戦えるようになったに過ぎなかった。 表立っての発言をやめ、活動も控えてひたすらに研鑽を積んでまで望んだスタートラインだ。 「いつか私は思い描くものが正しいことを証明していられるときが来るのだろうか」、そう思いながら「本質的には正しいが難なく成功へとはたどり着かない」道を(機械的故障などの不運にも見舞われながら)歩んでいた。

事業をはじめてからはなおのこと色濃かった。得意ではない、むしろできないという確信すらあることに手探りで進む。 何かを信じて目をつぶって飛び込むのはもとより行動力に難のあった私にとってはお得意で、多分最初は音楽家として弟子入りしたときだろう。 「いわゆる社会人としての経験もないけれど、教えてくれる人がいるわけでもないけれど、事業をはじめる」という決断は一見無謀で…しかしながら実際のところ戦えるだけの材料は揃えていた。なにせ、計画は5年も練って準備していたのだ。そのための研鑽だって積んだ。 私の中に判断基準ができるまで丸2年はかかったが、成果のでない中でも確かな手応えは感じていた。

コンピュータでも事業でも、その結実を問う成長の過程がしんどかったことは間違いない。 確かに昔とは違う、戦えているということに喜びを感じながらも、一方でうまくいかないことに苛立ちも感じていた。 もちろん、自分を納得させる方法はある。過去の自分がこのように戦えるかを考えれば一目瞭然ではある。だが、完璧ではない自分につきまとう不安は消えない。

私が不安の中で戦うことを覚えたのはバイクだった。 私はバイクの才能があった。だから、大概のことはできたのだが、これは「最初からできる」から経験による裏打ちがない。 できるという自信はないのだが、やってしまえばできる――という状態は私にとっては未知のものだった。 考えれば考えるほどできる気はしない、が直感はできると囁く。飛び込めば結果になる。だから直感を信じて飛び込む、自分の中にあるものを信じる、ということを私は覚えた。

この世界でもっとも存在する価値がないと信じさせられていた私にとって、超越の境地にたどりついたことは絶望であり、そしてそこからの道は自分に自分を証明するものだった。 冷静な観測者たる私は私に「できるだろう」と言う。いつからか、足は竦まなくなった。

いつのまにか追いついた実力

結実は2017年。ついに私は躓かなくなった。 机上の回答と実践の結果が一致するようになった。そしてついに、「経験のないことの結果を正しく予測できる」ようになった。

未知のことに対する見積もりというのはとても難しい。 だが、業務上、私は過去にやったことのないことをやらねばならないのであり、その見積もり(こちらは金額的な意味だ)というのはやる前に出さなくてはならない――やってから出していたら大赤字だ。 それ以前は結構なミスがあった。軽くみていて実際にやってみたらそんなに簡単な話ではなかったということのほうが多かったが、難しく見積もりすぎていて過剰だったことも1回だけある。 だが、コンピュータのスキルと、なにより経験が高まって考えるべきポイントがわかるようになってきた。仕事の経験を積んで金額の設定を行うポイントが見えるようになってきた。

迎えた2018年、いままでとは異なるタイプの難しい課題が続いた。 このような状況はどこぞのIT企業でも経験しているはずだ。 「今までやっていないことを要望されて、できるかどうか確信は持てないが、なにかしら回答はしなくてはいけない」。 わからないと言うのか、できないと言うのか、難しいと言うのか、調べるからと回答を保留するのか、などなど選択肢は豊富だ。 だが、受ければ私の場合はそこが最終責任なので果たさなくてはいけないし、安易には答えられない。だが、顧客を不安にしないためにもできるだけ正確に、かつ明確な答えを返したいところだ。

今年の難しい課題にはどれも、「検証しなければいけないので確実ではないが、アイディアはあり、できると考えている」という主旨で返している。 だが、この時点で私にとっては未知のテクノロジーも含まれていたし、正確にいえば守備範囲でもなかったので、さすがに確信をもって応えられない…のだが、私のうちには確信があった。「やったこと」はないから今すぐにコードが書けるわけではないが、使うべきツールは思いつくし、実現可能に思えるアプローチもいくつも思いつく。そこまでの責任がなければ「できるはずだ」と言っていただろう。

蓄積が導いてくれる

この感覚というか、嬉しさというかはなかなか伝えるのが難しい。 やったことはないのだ。特にできるという実績もないのだ。だが、確かにできるという感触があるし、その方法というのも私の中にある。調べながらとはいえ、今すぐに検証コードを書き始められるくらい(実際帰宅してそのまま検証コードを書いているし、その検証コードはいずれも理想的に動作した)なのだ。

言うなれば、私の中に、私より格上の私がいて、確信を持ちきれない私に「それはできるよ」と囁かれるような感覚とでも言おうか。 そして、それは確かに事実だ。正規ルートにある経験や実感を飛び越えて、私の中に積み上げられたものが直感となってその解き方を見せてくれる。 それは、根拠のない自信などではなくて、明確に答に導いていてくれていたことはすぐに、浮かんだイメージがどれも正解だったことで明らかだった。

あるいは、個人スポーツで大会でボロ負けしたあと、ひたすら基礎練し、ときどき元トッププロとの練習試合でボロ負けすることを繰り返した末に出場した次の大会で、前回ボロ負けしたはずの強敵が雑魚に感じられてしまう…みたいな感じと言ったほうが伝わるだろうか。

その未知のテクノロジーを扱う中で、予想通りでないことは当然に出てくる。 使ったことのないライブラリの振る舞いを熟知しているはずもない。 その場で試して、予想と違う振る舞いをし、「この方法は使えない」とわかる。 私は、「ちょっとこの方法はダメそうですね」と言うし、今用意していた手が使えないとわかれば、当然「ちょっと難しいですが、なにか方法を考えてみます」と言う――のだが、実際そのときにはもう私の頭は激しく動いていて、既に答らしきものを導きだしていた。 だが、まだそれは言えない。試さなければ確かなものではないし、打ち合わせの場は実験場ではない。責任者としては考えてみるという答は適切だ。 ――果たして、私は正しい答を既に見出していた。「難しい」と言いながら頭の中に浮かんだ式は、まさに望ましく動作した。あまりにも鮮やかに解にたどり着いてしまったがために、「難しいですね」と言いながらちょっと上の空はご愛嬌…ということにしていただきたい。

私がいつの間にそんな境地にたどり着いたのか、正直よくわからない。 コンピュータを追求したことのある身であればわかるだろうが、コンピュータにおいて「正しかろう」ことを考えることと、考えることが正しいことには著しい差がある。正しいと思ったことは大概一発ではうまくいかないし、一発でうまくいくことなんて本当に珍しい。

はずなのだが、私はそのことについて考えはじめたときには答がどこにあるかは見えている状態になってしまったわけだ。 まるで優秀な科学者のようではないか!!2

特に私に明確な成長の実感や、特別な自信があるわけではない。 どちらかといえば、その応答の根拠になった見積もりには自信がなかった。「思いついたものが間違っていたら、ちゃんと方法を思いつくだろうか。できそうな気はするけれども…」程度の気持ちで回答しているわけだ。 ところが、その回答を用意する間に実際には答が見えてしまっている。

つまり私の地力は、私が思う以上に確かなものになっていて、慎重な私の見積もりに反して、確かな答にたどりつくことができるだけのものになっていた。 それを為し得たのは、私がずっと成長や進歩を感じることができないまま、ずっと戦い、躓き続けてきた中で積み上げてきたものがそうさせるのだろう。

だから、改めてすごく実感した。 例え確かな実感がなくても、そうやって積み重ねてきたものは、蓄積は、裏切らない。 確かな力になっているのだと。


  1. 最も大きいのはやはりLUKSが解除不能になりかなり多くのデータを損失したことだろう。

  2. 「随分と難しいことを言うな君は。そんなことしたこともないからわかるわけがないだろう。 …いや、でもそうだな…あれをこうして…いや、そうだとあれが問題になるから… あぁ、そうだな。ちょっと思いついたことがあるんだ」 みたいな感じ。

21.5インチFHDと32インチ 4kディスプレイをLinuxで混ぜる

なにをしたか

あらまし

私はディスプレイは「随時買い足す」スタイルできた。 それも、主にリサイクルショップで買い集める形だ。

台数が多く、並行作業も多いので、接続数の関係上どうしてもディスプレイが増えざるをえない。

そうした中、ずっとメイン環境を支えてきたのがLGの22EN33及び22EN43である。 支えてきた、と言うと良さそうに聞こえるが、私にとっては最悪なディスプレイである。 輝度調節がおかしいし、色味も最初からぶっとんでいて調整の意味がない。挙げ句、ドット抜けはあるし、ちょっと触れただけでも傷はつくし、アダプタは激しくコイル鳴きするし、一度は液晶抜けするし、LGのサポートは「何も問題はない」と突っぱねるし、もう二度とLGのディスプレイは買わないと心に決めるくらいはひどかった。 似たようなサムスンのS22B300は非常に素晴らしいディスプレイなので、サムスンがPCディスプレイをやめたのが残念でならない。

基本的に輝度や色味などのぶっとび度合いは22EN33のほうが悪いが、傷がついたりドット抜けしたり壊れたりとトラブルが多いのは圧倒的に22EN43である。そして、その22EN43が、ついに画面全体に乳白色の何かを浮かべるようになってしまった。

困ったものだと思っていたところ、なんだかちょうどよくアウトレット品の4kディスプレイ、AcerのET322QKがえらい安くで出ていたので即決してきた。

解説

これは、もうちょっと説明がいるだろう。

私のディスプレイは圧倒的に21.5インチFHDが多いが、これはFHDディスプレイとしては安いためである。叩き売られることも多いし、中古も潤沢だ。

基本的にはやや小さいが、DPIとしては101ないし102程度であるため、これ以上大きいと96を下回ってしまう。解像度的には無難な線だ。

4kに変更したい、というのはずーーーっと前から思っていたこと(10万円くらいの4kディスプレイが出始めた頃から)なのだけど、その場合27インチを本命としていた。 これは、視線移動量と視点距離を考えたときにこれ以上大きくなってほしくないからだ。 一方、21.5インチや24インチの場合、4kになることで密度が上がり、必然的に多くの情報を表示できることから、より色々と表示できるし、ウィンドウのクォータータイリングも現実的になる…はずなのだが、24インチや21.5インチの4kではあまりにも表示サイズが物理的に小さいため、結局左右タイルが限界であり、あまり情報量が増えない。 27インチもまぁまぁきついが並べるには限界サイズである。

私のディスプレイは基本的にメイン2+サブ1という使い方なのだが、今回は事情が事情だし、2枚は買えない。 そこで1枚だけ置き換えるのだが、そうするとメインディスプレイ同士で表示サイズが著しく違うという事態が生じる。

32インチはちょっと大きすぎるが、おけないこともない(32インチ2枚は机のサイズを考えても現実的でないくらいは厳しい)し、DPI差が小さく、妥協できるセッティングが出しやすい――このことはこの記事のこのあとの話で延々触れる。

ちなみに、アウトレット(展示品)というといまいち感があるが、ディスプレイの場合保証があったところで対応されづらいのが現実である上、対応されることのないドット抜けや表面の擦り傷というのがあって賭けみたいなところもあるので、動いている実物をチェックした上で買えるのはむしろメリットだと思っている。

今回は、これまで理解はしていたが、実際に混ぜてみたことで改めて実感したことを述べていこう。 もちろん、Linux前提である。

小さい? 大きい?

実測値としてはLG 22EN43は幅47.7cmで1920px (102dpi)、 ET322QKは幅69.3cmで3840px (140dpi) である。

102 / 140 = 0.728571427571… であるため、ドットは72.857%(約3/4)に小さくなったことになる。

逆に、ET322QKをFHD表示にした場合は145.71%に拡大されることになる。これは、単純に21.5インチディスプレイから同一解像度(FHD)のまま32インチディスプレイに変更した場合と同様のことである。

これは一辺を見た数字だし、基本的にコンピュータ上で表示されるものというのはボックス状なので、面積で言うと53.08%まで小さくなっているのでだいたい「半分になった」という感覚だし、FHDのままだと212.31%と「倍になった」感じがする。もちろん、ディスプレイの表示面の面積自体倍以上に大きくなっている。

これをまぜたとき、FHDで統一するともちろん4kディスプレイのほうが物理的に大きいぶん大きく表示される(倍以上に!!)のだが、実はこちらはあまり気にならない。 「大きいテレビで引き伸ばされた画面を見る」というようなことに慣れているからだろうか。実際、その画面を見ると「ギザギザでぼんやりしているなぁ」と私は思うのだが、でもそこまでみづらいということもない不思議だ。

ところが、FHDで適性なサイズにしている状態で4kに表示させると表示サイズが半分になっていながら表示する空間は4倍ある(表示可能な量は4倍にしかなっていないのだが、「半分のサイズで表示されている」「空間は4倍になった」というそれぞれ別の感覚が相乗効果を発揮する)のでやたらがらんとして見えるし、やはり適正サイズの半分というのは小さすぎる。 高密度になっているので意外と文字も読めるは読めるのだが、しかしながら非常にきつい。4kを4kとして運用する以上、元のままのスケールではちょっとやっていられない。

ちなみに、32インチのディスプレイは問答無用で大きい。一枚だけ使うにしてもかなり距離がないと大きすぎるくらいで、マルチディスプレイするサイズではないな、と感じる。

混ぜる場合どうスケールさせる?

4kのほうがいいディスプレイだし、物理的にも大きいので4kをメインに考えるべきだろうと思うのだけど、 72.857%ということは、元の状態でスケールしていなかったとしたらだいたい1.4倍にするとFHD側の元の状態と同じ物理サイズになる。1.5倍だとちょっと大きい。

ところが、1.4倍にスケールさせてしまうと、FHDの論理ピクセル数は1370となるため、HD(FWXGA)と同等になる。縦は771ピクセルである。 21.5インチのHDディスプレイというのは実在したが、ちょっと狭い。ウィンドウをタイルして並べるとやたら文字も大きく表示領域がまるで足りない感覚になる。

だから、間をとって1.2倍(あるいは1.25倍)というのがよさそうではある。フォントサイズは少し大きめにしたほうがいいかもしれない。4k側で文字が小さく感じるかもしれないし、部品が多少小さくなるのに比べて文字が小さくなる影響は大きいからだ。

1.2倍スケールの場合FHDの論理ピクセル数は横1600ピクセル、1.25倍スケールの場合1536ピクセルになる。1.25倍だとちょっと狭いが、1.2倍ピクセルなら「なんか表示が大きい」程度で済ませることもできそうな感じである。 MacなんかはUIが大きくぎっしり表示されるので、それが気にならない人は普通にいるだろうし、悪くないかもしれない。

試した結果は結局「間をとる」という無難な結論になってしまった。

ちなみに、今回の場合21.5インチFHDが2枚で32インチ4kが1枚という構成であるためにあまりFHD側を無視するわけにもいかなかったが、これが4k2枚でFHDが補助ディスプレイであるという話であれば1.4倍スケールでも別に構わないだろう。1370ピクセルあればウィンドウを常に最大化してしまえばそんなに気にならない、というか、そもそもラップトップが実DPIに合わせてスケールするとそれよりも小さくなるのが普通なので(私のThinkPad X1 Carbon(14インチ FHD)は148DPIでスケールされているため論理ピクセル数は1228である)表示スペースが足りずにはみだすようなことはあまりない。

それぞれスケールできない?

できない、らしい。

Windowsだとディスプレイごとに「拡大率」という値を設定できるようになっている。 この拡大というのはまんまスケーリングを意味しているので、ここで175%を設定すると論理1ピクセルに対して1.75ピクセルをカウントするようになる。

だが、この設定が今のところLinuxでは上手くできない。 最もスケーリングが細かくできるのはKDE Plasmaだが、それでもディスプレイごとに独立した設定はできないようになっているようだ。

xrandrを使うことで設定自体は可能だが、少数の値を設定してしまうとフォントがすごく汚く表示されることになる。

だから、現時点ではディスプレイごとのDPI差を適切に埋める完璧な方法はない、ということになるだろう。

フォントだけ合わせるという方法

今回の場合、51.6%に縮小されるもののUIのサイズとしてたいていの場合は51.6%というのは私にとっては許容できるサイズに収まった。

そこで、私がとった方法がこれだ。

実DPIによる影響が最も大きいのは「文字サイズ」であるため、LinuxでもUIスケーリングとは別にフォントはスケーリングできるようになっている。

そして、フォントのスケーリングの構造はちょっとめんどくさい。

フォントの場合96を1として、設定されたDPIの倍率にスケールされる。 つまり、144DPIを設定した場合、144 / 96 = 1.5 なので、1.5倍にスケールされる。

フォントにおける1は1ピクセルであり、1ポイントでもあるのだが、両者は同時にスケールされることになり、基本的には同一視できる。 FontConfigは144DPIを設定した場合、16pxを求めても、16ptを求めても、24実ピクセルで描画する。 問題はビットマップフォントを使う場合だが、その話は割愛する。

基本的に115.2DPIにすれば1.2倍スケールとなる。120DPIで1.25倍スケールだ。 UIと比べ柔軟に設定できるので、このあたりを参考にバランス良い設定になりそうなDPIを設定すると文字側は調整できる。

私は今のところ120-136DPIの範囲で様子を見ている感じだ。 KDE Plasmaの場合、ほとんどのアプリケーションはPlasma Workspace側で設定されたDPIに従うが、ConkyはFontConfig設定ファイルを尊重するため、Conkyのサイズ調整を目的に異なった値を設定する方法もある。

あとは、積極的にフォント側DPIを設定してからUIスケーリングでバランスをとる、という方法もある。 この方法はもっと実DPIに差がある場合の解消方法として使える。 また、フォントのみで解決する場合は細かなUIスケーリングがいらないため、「Hi-DPIのためにKDE Plasmaを使わなくてはならない」という状況を避けられる。 (KDE Plasmaは0.1倍単位でUIスケールできる)

もはや、DPIとかピクセルとかポイントとかいう、定義が明確であるはずの言葉が相対的なものになってしまっていて意味がわからないが。

なお、フォント設定でスケールする場合に特に重要なこととして、「普段GTKデスクトップを使っていて、スケーリングのためにKDE Plasmaにスイッチした人」は、.xprofileなどでexport QT_QPA_PLATFORMTHEME=qt5ctとかしているのであれば、それをやめないとKDEの設定がちゃんと反映されず、GTK2アプリケーションにも反映されない。

また、この方法を取る場合、パネルだけはCinnamonもPlasma Workspaceも高さがピクセル単位になっているため大幅に小さくなってしまう。このため、パネルの高さは再調整が必要だ。 私の場合、サブディスプレイ上にパネルを置いているため問題はなかった。

ブラウザのスケーリング

ウェブブラウザはちょっと特殊な事情を持っているようだ。

Chromium系(ChromeもVivaldiも)ブラウザはフォントのDPI値が約110%以上(103以上?)であるとき、そのDPI値に合わせて10%単位でスケールするようだ。 これはブラウザをズームしたときと同じ挙動だが、困る場合がある。

これによってパーツがはみ出してみづらい場合があるが、これについてはまだズームを落とせばいいので許せる。 問題はフラゲ(フラッシュゲーム)である。 見た目が汚くなる上に動作が遅くなって非常に辛い。

なお、Firefoxはまた事情が違うのだが、layout.css.devPixelsPerPx1にすれば自動スケールは行われなく成り、-1にすると自動的にスケールされる(多分、UIスケールによるのだが、DPIによるのかもしれない)。この機能に関してはlayout.css.dpiも絡む。

実際、メイン/大きな4k * 1 + サブ/小さなFHD * 2 ってどう

だめ。 どうしたってみんな4kを取り合ってしまう。

なにをするにも大概大きい4kっていうのは便利で、できればそこに置きたいという気持ちが強い。 みっちり書かれている文章だとそうでもない(FHDの全画面表示でもテキスト量が多すぎる)けれども、なにかしら情報が付属していたりマルチペインだったりするのが現代なので、たいていのアプリケーション及びコンテンツが4kを奪い合う。

サブは私の場合メール, Discord, Twitterなんかになるのだけど、これらは基本的にリアルタイムで見続けるようなものでもないからそれぞれ全画面化してサブに置いているものの、4kだったらモニタリング機能とか作ってタイルして色々表示させてもいい。

だから特に必要ないものも含めてたいていのアプリケーションは大きな4k(もちろん、適切な大きさの)を欲しがる。 21.5 FHDを回転させて縦にするとバランスはいいが、表示できるものはさらに少なくなる。

32インチを複数置くのは難しいので、やはり27インチ4k*2 + 21.5もしくは24インチFHDというのがバランスがいいと思う。 逆にサブを32インチ4kにして少し離してモニタリングに使う手もあるけど。

Acer ET322QKってどう (2018-12-03 追記)

基本的には悪くないと思う。 少なくとも22EN43/22EN33のように色味がおかしくて輝度もおかしくて視野角も異様に狭いといった問題はない。 特別良いということもないけれど、かといって目立った問題があるわけでもない。

特別良いというわけではなく、色味も標準(というフラット設定)ではフラットではないため、アートワークの作業をするクリエイターにはとても耐えないし、ゲーマーにも無理だろうけれど、 動画視聴程度であれば遅延が気になるということはないし(ただビデオカードのほうは4kなのでちょっと重いけど)。

色味も、特に優れたところはないけれど、別に使えないことはない。一応sRGB 100%らしいので、カラーキャリブレーションすれば結構使えるのかもしれない。

目立った問題としては入力端子が3系統(HDMI 2.0×2, DP 1.2×1)であることだろう。 台数が多いとなるべく集約したいので、端子はなるべく欲しい。 私の環境だとDVI-Iが多いけど、別にDVI-ItoHDMIは可能なのでHDMIで良しとして…

メーカー モデル ポート
IO DATA EX-LD4K271DB D-Sub, HDMI(2), HDMI 2.0, DP
IO DATA KH2750V-UHD D-Sub, HDMI(2), HDMI 2.0, DP
BenQ EL2870U HDMI 2.0(2), DP
LG 27UK650-W HDMI(2), DP
iiyama ProLite B2875UHSU B2875UHSU-B1 DVI, D-Sub, HDMI 2.0, DP
JAPANNEXT JN-IPS27FLUHD HDMI 2.0(2), DP(2)
DELL S2817Q HDMI(2), DP, miniDP
ASUS VP28UQG HDMI 2.0(2), DP

JAPANNEXTがIPSで消費電力も最大35Wと低いのに安くてなんか強い。 それはともかくとして、以前のように端子数5を越えるものは減っている感じだけど、3というのは結構少なめ。 端子数4は普通に狙えるので、そこは残念ポイントな感じがする。

最大の難点は、起動が遅いということだろう。 EIZOとかも遅いので、品質の問題ではないけれど、結構遅い。そして、切り替えも遅い。信号がなくなってから再び信号を捉えるまでが長い。

「待てばいいじゃん」と思うかもしれないが、実は KDE Plasmaでは深刻な問題になる

KDE Plasmaで思わぬ問題 (2018-12-03 追記)

KDE Plasmaの場合、ディスプレイに対してディスプレイの接続方法ではなく、「ディスプレイの認識上の番号で」識別する。 KDE Plasmaはディスプレイを中途半端に重ねることも可能で柔軟なのはいいのだが、応答の早いLG及びサムスンのディスプレイはすぐつくのだが、このときKDE Plasmaは「ディスプレイが2台しか接続されていないように見間違う」。

つまり、左から

  • LG HD
  • ET332QK
  • サムスン HD

と並んでいて、パネルはサムスンの上にあるのだが、 このときこの並び順に最初にKDEにログインした時点では認識されている。 だから、パネルは3番ディスプレイにある。

ところが、一時ブランクスクリーンになって復帰すると、ET332QKの認識が遅れるためにサムスンが2番になり、ET332QKが3番になる。 結果としてサムスンとET332QKの壁紙が入れ替わり、パネルはET332QK上に移動してしまう。 さらに、なぜか中心座標を見失ってしまって、Conkyが1920pxずれる。

3台であれば右にあるディスプレイをプライマリディスプレイにすることで1番を固定すればET332QKが最後にくるように固定できるから問題は軽減される。 だが、アンバランスな配置のせいかPlasmashellがバグることが多い。さらに、どうしても左側のディスプレイをy:1081に固定するのが難しい。y:0になってしまう。

また、マルチディスプレイではKDEはフルスクリーンにしたときにパネルの表示がおかしくなる。 パネルの表示の上に古いパネルの表示がかさねられたようになる。つまり、以前同アプリケーションでフルスクリーンにしたときと同じ状態になる。 確実になるわけではないが、一度発生するとフルスクリーンにするたびに再現しつづける。

結局、私はCinnamonに戻した。 フォントのスケーリングを中心としてUIスケーリングしないことにしたため、これでも問題はない。

CinnamonのフォントスケーリングはDPIではなく倍率になっている。 0.1倍単位だが、1.25倍で120DPI, 0.1倍あたり9.6DPIというのを基準に考えれば良いだろう。 今の状況を考えるとこちらのほうが素直だろう。

このままではQTアプリケーションが小さいので、.xprofileQT_SCALE_FACTORを設定しておくと良いだろう。 1.2とか1.25あたりが無難な値になるだろうか。

ところがCinnamonでも… 原因はDP (2018-12-05 追記)

Cinnamonなら大丈夫と油断していたところ、Cinnamonでもブランクスクリーンに落ちるとおかしなことになってしまった。 パネルがおかしくなるといったことはないのでKDE Plasmaよりはマシではあるものの、好ましい状態ではない。

どうも他のディスプレイでは発生しない症状として、「電源がオフになると切断される」らしく、問題はディスプレイの電源を切っても発生する。 そして調べていくと、「DPの仕様」らしいとわかった。なるほど、確かに他の2台はminiDP→DVI-Iで接続しているのでDPではささっていない。

WindowsだろうがLinuxだろうが、ディスプレイのホットプラグで問題が生じないなんてことはないので、これは大迷惑である。ディスプレイを共有して作業していることなんて普通にあるのだし… 実際、この挙動は相当強く嫌われているようだ。

なんとかしようとがんばって/etc/X11/xorg.conf.d/90-mhwd.conf

Section "Device"
    Identifier     "Device0"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
        Option "NoLogo" "1"
        Option "UseHotplugEvents" "false"
        Option "AllowEmptyInitialConfiguration" "true"
EndSection

などと書いてみたものの残念ながら効果はなし。

ただ、この場合問題ははっきりしているので、本気になればやりようはある話だと思う。 とりあえずは私の場合ディスプレイの電源を切らないように設定してしのいでいるが、困るのは「通し作業のときにディスプレイを切って節電する」という方法がとれないことだと思う。

そのうち何か考えて対応したい。

がんばって解決した人がいるようです (2018-12-16追記)

Twitterでのやりとりを経てエヌユルさんがxrandrを使う方法で解決した旨ブログにかかれていました

実はこの方法、私にとっては既知で、以前のスケールとDPIのアーティクルを含めて「あんまよくないので言及を避けていた」方法だったりする。 しかし、参考にしてもらえるなら、もっとちゃんと説明すればよかったな、この方法でよかったなら悩ませずに済んだのに…と割と後悔している。

手順、及び結果はどうブログの記事の通りである。 ちなみに、ディスプレイ位置が上限に合わせられてしまうのは「0,0にディスプレイを欲しがる」からで、左のディスプレイが4kなら問題ないのだが、そうでないとFHDディスプレイを上にあげたがる。 Plasma Workspaceだと勝手に修正されてしまったりする。

私が言及を避けたいと思う理由は次の通り

  • ディスプレイをネイティブ解像度以外にしたときのようなもやっと感がある
  • xrandrのスケーリングはFTより後段にあるため、字の描画が大変汚い
  • Plasma Workspaceはひょんなことでこの設定をリセットしてしまうのでえらいことになる(パネルが吹っ飛んだりする)。 これは、ワークスペース切替時、アクティビティ切替時、ロック時などに発生しがち
  • DPのホットプラグ切断による問題がより深刻化する
  • 私としてはUIサイズはそれほど気にしないがフォントサイズの落差が辛い、ということを問題にしているので、FHD側を1/4角にするというのはフォントサイズの設定において事情が変わらない(単に元はFHDが4倍角だっただけの話なので、DPIをだいたい中間に設定するという話から動かない)

UIスケーリングに関しては、現代においては「ブラウザ(特にBlink系)がフォントDPIに従って勝手にスケールしやがるので、中間DPIを設定しておけばだいたい許せる結果になる」というのが私の感想である。 画像を見たり、VSCodeとかAtomを使う分には割とどうとでもなるので(ディスプレイを4k/FHD間で動かすのは大変だけど)、「フォントサイズさえ妥協できるサイズにしとけばいいや」が私の現状の結論。 もちろん、言うまでもなく「ディスプレイごとに適切スケールさせろ」と言いたいところだけど、未だにNvidiaがLinuxでマルチヘッドディスプレイに対して雑な対応を続けているあたりを考えると、多分無駄な主張になるだろう。 世の中マルチヘッドディスプレイが当たり前になっていっているわけでもないし。

あと、本題とは関係ないが

世の中のwebサイト巨大ディスプレイに最適化されてなさすぎですね.

これについてはDPIと画面サイズとスケーリングとピクセルの話で書いているけど、基本的に現代においては「1ピクセルが物理的1ピクセルを意味しない」というスケーリングの方向であり、 14インチのThinkPad X1 Carbonですら横の論理ピクセルは1288pxである。12.5インチのThinkPad X280では1047pxしかない。 この方法は、そもそも「物理的にピクセル数が増えても論理ピクセル数は増えない」というものなので、XPS13の4kを使ったところで、論理ピクセル数は1200pxに満たないのだ。

私はFCとしては120dpiに設定しているので、ブラウザは1.2倍にスケールするのだが、それでも4k側だと3200pxも幅があることになる。 さすがにこれを「想定しろ」というのは無理な注文だと思っている。 4kを使うならウィンドウをタイルする、で良いのではないだろうか。大きな4kディスプレイを持っている人はある程度知識がある人のほうが多いし、安全側に倒すならそちらを優先した設計はできない。

どちらかといえば私が考慮すべきなのではないかと考えるのはChromium及びFirefoxのテーマだ。 あれらは全くスケールしないため、4kで最大化すると画像サイズが足りずすっかすかになる。