投稿

Karma Chameleon

イメージ
今日、ABBA が何十年ぶりかに新曲を出すとかいうニュースがあり、そのつながりで、Youtube で ABBA の曲など視聴していたら、関連リストの中になぜか一つだけ ABBA ではなく Culture Club の Karma Chameleon が紛れ込んでいたのが目に付いた。 中学 1、2 年の頃だったと思うが、学校の英語の先生(女性)が、授業でこの曲を聴かせたりしたのを思い出した。その頃の記憶では Karma というのはカーマという女性の名前の意味だと言われていた。その先生がそう教えたのか、ラジオなどでその曲を流す際の解説でそういう風に言われていたのか、どちらかは定かではない。ともかく、昔中学生の頃この曲を初めて聞いた記憶と共に、「この曲はカーマという移り気な女性に翻弄される男の気持を歌ったものだ」という情報ははっきりと記憶に刻まれている。 今や英語に関しては完全に DIY で接することができるので、ふと、この Karma が、「カルマ(仏教用語の「業」)」のことなんじゃないかと思って物凄く気になり、確かめてみたくなった。映画の邦訳など日本の文化系分野の英語業界の詐欺紛いには最近常々目敏くなっているので、どれ、音楽業界の方はどうなんだい? と。 まず、 Music Video を観ても、Karma がカルマの意味であることは一目瞭然である。一人のスリかつ詐欺師の男が、フェリーの女性客たちの装飾品を盗み、さらに男性客たちからはイカサマで金を巻き上げる。調子に乗り過ぎたせいで、イカサマと盗みがばれ、袋叩きにあい、男はフェリーから放り出されて悪事は破綻、カルマの法則的な因果応報の結末を迎えるというストーリー仕立てになっている。 次に、実際の英語の歌詞を調べてみた。確かに、この歌詞を文章化したものだけを見ると、今度は、「女性に翻弄される男の気持」という構図とするのは、大きく間違ってはいない。反対に、Karma =カルマとする場合、この歌詞を深読みする必要が出てくる。もちろん、歌詞(詩)というものは一つの言葉を多義的にして深みを持たせるのが普通なので、「表面的にはカーマという女性のことを歌っていて、実際はカルマのことを暗示する」なんて話はよくあることである。 三番目に、ちょっと Web を調べれば見付けられるが、ボーイ・ジョージ自身のこの曲の意味につ...

EP-805A 廃インク吸収パッド交換

イメージ
知人からエプソン製の複合機カラリオ EP-805A が廃インク吸収パッドの交換を促す警告表示(「廃インク吸収パッドの吸収量が限界に近づいています。お早めにエプソンの修理窓口に交換をご依頼下さい。」)が出るようになったと相談を受けた。 事務などでガンガンに使い倒しているわけでなく、基本的に個人用途でのチマチマとした使い方しかしておらず、純正インクのみで大切に使ってきたものなので、まだ結構新品同様に元気に動いている印象だったが、もうそんな時期なのかと。 実際のところ調べてみると以下のようだった: 発売日 2012-09 購入日 2013-06-17 修理対応期限 2018-07-31 サポート切れまで間近に迫っている。発売から 5 年 11 ヶ月でサポート終了ということのようだ。 ところが、エプソンの 公式ページ を調べてみると、まだサポートを受けられるといっても、その金額に唖然とした。税別で、基本料金 11000 円、廃インク吸収パッド交換費用 4000 円、送料 1500 円と、総額 16500 円也! 新品が 15810 円で購入できたものを、今や 5 年型落ち状態になってなおかつ 16500 円で修理って、そんなアホな……。どう考えても、修理させるつもりないでしょう、エプソンさん。まあ、プリンター産業に関しては、国内企業なので、儲ける側の国益と、消費する側の国益を秤にかけると、単純に一方的に消費者の側の立場だけでエプソンを責める気にはならないのだけど(一方、プリンターが自国産業というわけではない フランスで、エプソンやキヤノン、ブラザー、HPを訴訟する のに何のためらいもないのは当然の話)、これはいくらなんでも酷い。せめて半額程度だろうと思う。 それで、ちょっと調べたら、自分でプリンターを分解して吸収パッドを交換し、ソフトウェア的にカウンターもリセットしている人がいるということを知った。まあ、捨てて別の新品に買い替えることを考えるならば、ダメ元で試しても損はないということで、やってみることにした。 参考 分解方法 :EP-805A の型番のプリントされた前面パネルの取り外し・取り付けにコツがいる。下側を回転軸にして、上部のツメを外しながら外す(取り付ける時はその逆に下側を回転軸にして、上部に被せていくようにしてツメには...

パケ死

先月(昨年)末、友人から中古で iPhone 6s を買い取り、ついに iOS デバイスのオーナーとなった。SIM を挿し替えて、Apple の移行ツールを利用して、ほとんどの設定が Android から自動で移行できた。だがその移行過程で、「モバイルデータ通信」を OFF にする間もなく、アプリのアップデートなどが始まり、数十秒後に気付いて処理を中断したものの、時すでに遅し……。数十秒で 89 MB のデータ通信が発生してしまった。 ドコモ口座を使いたいがためにドコモと契約してかれこれ 1 年と 2 ヶ月になっていたが、契約プランはカケホーダイで、パケット定額は契約せず、スマートフォン側でモバイルデータ通信を常時 OFF にすることによってこれまで何の問題もなく利用してきた。しかし、ほんの数十秒のミスで発生したわずか 89 MB のデータ通信に対するドコモの請求が、これ:(画像消失) 53,972 円 なんでパケット料金が何十年も前の携帯電話が主流の時代の単価のままなんだよっていう。 よく、総務省の有識者会議とかで携帯キャリアの規制について話題になってるけど、パケット単価の問題を放置して、他の何を会議で話し合っても、「何が有識者なの?」「何が国民の利益なの?」ちゃんちゃらおかしいと思う。 夜更ししていて寝る前の最後の一仕事のつもりでやったのがこういうことになって、ショックを受けたが、どうしようもないので、諦めて寝た。翌日、思い直して調べてみると、こういう事態が「パケ死」と呼ばれていることを知った。どちらかというと「パケ死」は、海外ローミングで発生する事態のようで、僕のように、意図的にパケット定額をしないで国内で普通に生活していて起こる事態は主流ではないようだ。 さらに、「パケ死」というキーワードをベースにして調べてみると、他にもこういう目に遭った人は少なくないようで、救済措置が存在することもわかった。ドコモの場合、一回だけ、遡って後付けでパケット定額に加入できるという。早速ドコモのインフォメーション(151)に電話してお願いし、最低額のパケット定額を適用してもらって、どうにか事なきを得た。 一度こういう事故に遭ってしまうと、たとえ以前より慎重に気を付けていたとしても、事故が起ってしまったらパケット料金が青天井であるということは恐しくて仕方...

HTTP/1.1 Transfer-Encoding: chunked

Web Scraping 用のプログラムを組んでいて、HTTP レベルの Socket プログラムを自前で組むか、Client レベルの処理は言語環境のライブラリーに任せて HTML を解析・処理する程度のものを組むかという、二択問題によく悩む。これまでの経験上、後者の方が敷居が低く取りかかるのに容易であるというメリットがある。一方、一旦何らかの壁にぶち当たると、ブラックボックスのない前者の環境で試行錯誤を進めた方が、心理的にもまさしく“急がば回れ”の典型のような結果となり、トータルで楽になる。 そんなわけで、今回取り組んでいる物件についても、スタートアップは Java の URLConnection で一通り組み上げてしまって、それで問題なく全体的に動くものが出来上がっていたので、そのまま運用していたものだった。ゼロ状態からのスタートとなるプロジェクトでは、まずはどんな形であれ、全体としてちゃんと動くものへと到達できるかどうかが不明な状態なので、「まずは全体としてちゃんと動くもの」まで辿り着くことが何よりも重要である。そのためには、Client レベルのものは Java のコアライブラリーに任せて、Web Scraping にターゲットを絞った方が確実にプロジェクトを成功まで推進することができる。 それでそのまま動くようになったままで運用し続けていて、プログラムには手を入れていなかったのだが、今度、Lanterna を使って GUI 化したりして、使い勝手が向上したので、さらに前から欲しいと考えていた機能を追加したりした。最終的には GUI 化したらしたで CUI の時は気にならなかった処理速度が気になったので、ネットワークからのデータの読み込みをマルチスレッド化するところまで行き着いた。 このネットワーク読み込み処理のマルチスレッド化で、ある問題が表面化したのだった。 どうやら Java の URLConnection は、スレッドセーフではないようなのだ。とはいっても、このプロジェクトに関して言えば、Cookie がスレッド間で共有されていることが問題の核心であり、それを URLConnection 自体がスレッドセーフではないという話に含めていいのかどうかはわからない。ともかく、Cookie が上書きされてしまうのが原因で、サーバー側が付与する JS...

Exception の使い処

Perl では Exception のことは気にしないでプログラミングできたので、Java で当初特異に感じたのが Exception の扱いだ。仕様に強制される形で try-catch を行う必要があるという認識で今まで凌いできた。 そもそも CUI でプログラミングしている段階では、例外処理については別段の配慮はせずとも、コンソールに JVM が吐くエラーメッセージが表示されるので、自分でエラーに備える処理を明示的にコーディングする必要はなかった。CUI というのはそういった意味でユーザーとプログラマーが完全に同一レベルの視点で体験を共有しているので、ある意味貴重な環境なのかもしれない。 そういった CUI の貴重な環境の習慣をそのまま引き摺ってしまっていて、GUI で Android のアプリなどを作っていても、例外処理について、標準メソッド側が要求するから受動的に try-catch を記述する程度で、自分から能動的に Exception クラスを用いるという経験があまりなかった。 ところで最近 Web のフォーム送信操作を自動化する Java プログラムを作成していて、想定外のエラーが発生した時、そのエラーがどの段階で出たエラーなのかということがわかった方が、自分自身で利用するだけでなくもしアプリを公開するという前提では、その方が良いと考えた。そこで、各段階で、想定通りではない結果になっていた場合、Exception を発生させるようなコードにすることにした。 当初は字義的に、RuntimeException を使っていた。ところがこれでも「どの段階で発生したのか?」がわかりにくかったので、最終的には IOException を使うことに落ち着いた。 GUI ライブラリーとして Lanterna という ncurses ライクなライブラリーを使っており、コンソールではなく、GUI の表示にエラーメッセージも表示させたいと考えた。当初の RuntimeException だと、どこかでエラーが発生していることがコンソールには表示されるのだが、どの段階で起ったのかが把握しにくく、GUI 側でもどこでキャッチすればいいのかがわかりにくい。そこで IOException にして、GUI 側で catch させることにしたのである。 ネットワークにアク...

APFS は case-sensitive で

APFS を何も考えないでデフォルトのままフォーマットして macOS High Sierra をインストールして使っていたが、case-insensitive であることに気付いて、再度、SSD を完全に初期化し、case-sensitive フォーマット(非暗号化)にして、High Sierra をインストールし直した。 通常は、APFS を case-sensitive にする必要はなく、例えば、Android Studio(Android 用のアプリ開発環境)ではシステムのフォーマットが case-sensitive だと警告が出たりする。一方、OpenWrt のような Linux 系 OS のカーネルをクロスコンパイルする場合、Linux は case-sensitive なので、macOS 側でも case-sensitive である必要がある。そういったレアケースに対応したいのであれば、case-sensitive にしておく。そうでない場合はよっぽどでない限り、case-insensitive が無難だろう。 OS インストール後の各設定のカスタマイズや、基本ツールのインストールなどは、一度それぞれの方法を確立した後だったので、今回はそれらを通してメモにまとめておくことができた。FileZilla の設定 .xml はちゃんと iCloud ドライブに退避させておかなければならない、などの要点を整理するいい機会だった。 ちなみに、なぜ非暗号化でフォーマットしたかというと、一度暗号化でフォーマットしたのだが、OS のインストール後、暗号化されたドライブ用のユーザーアカウントが表示されるようになったので、気持悪かったので、非暗号化でフォーマットして仕切り直した次第である。OS のインストール完了後に、FileVault を有効化して暗号化したが、完全に暗号化が終わると、APFS のフォーマット自体が暗号化されたものに置き換った。ということは結局、最初から暗号化しておいた方が、時間的に遠回りしなくてスマートだったことになる(意味不明のユーザーアカウントはどうにか消す方法がある)。

QNAP の SSH のアクセス元制限の不完全な仕様

OpenVPN で実家の LAN につなぎ、VPN 経由で NAS(QNAP)にアクセスできるようになったので、ネットワークセキュリティを強化すべく、NAS の SSH にアクセス元制限を付けた。/root/.ssh/authorized_keys の公開鍵リストに、from="(ネットワークアドレス)" のオプション設定を追記したわけだ。 ところで、元々ブリッジモードの VPN 設定だったのを、ルーターモードに変更したため、アクセス元のクライアント機のネットワークアドレス(192.168.11.0/24)は NAS 側のネットワークアドレス(192.168.0.0/24)と異なるものとなった。そのため、from にカンマ(「,」)区切りでネットワークアドレスを列挙する必要がある。 from="192.168.0.0/24,192.168.11.0/24" ssh-rsa AAAAB3N... しかし、どうやら QNAP の SSHd では仕様が不完全なようで、from として列挙したものを与えると、正常に動作しない(すべてのネットワークからアクセスできなくなった。仕方なく、一時的に telnet を使って復旧作業をする羽目になった)。 つまり、authorized_keys の from 設定としては列挙で設定することはできず、一種類の設定しか与えることができないのである。 簡単に思い浮ぶのは、VPN をルーターモードで運用するのをやめて、ブリッジモードに戻すことである。そうすれば、クライアント機のネットワークアドレスは NAS 側のネットワークアドレスと同一なので、from のエントリーは一種類で済む。 それでもせっかくルーターモードにしたのにブリッジに戻すのも何となく嫌だったので、(専門家でもないのに独学でネットワークエンジニアの資格をパスしたという“昔取った杵柄”を活用できたのか)ポク・ポク・ポク・チーンと思い付いたのが、ネットワークアドレスに、192.168.0.0/23 という値を使う方法。 23 ビットというネットマスクを使う奇策 である。この設定は、192.168.0.0 〜 192.168.1.255 の範囲の IP を意味するネットワークアドレスである。 from="192.16...

OpenVPN を TAP(ブリッジ)→ TUN(ルーター)へ変更

イメージ
基本的に VPN と NFS を使った利用環境は構築できたので、最後に少しでも VPN を最適化しておきたくなり、OpenVPN のモードを TAP(ブリッジ)から TUN(ルーター)へ変更することにした。 .ovpn まずはサーバー(DD-WRT)側と、クライアント側(Mac、Linux)双方で、.ovpn 中の dev 設定を tap から tun に変えることが基本となる。 dev tun クライアント側はこれだけで他にやることはない。一方、サーバー側ではルーターモード制に伴ういくつかの副作用的な状況を解決するための設定が必要となる。 サーバー(DD-WRT)側 設定中で tun にする以外に、VPN 専用のサブネットの設定が必要になる。DD-WRT の設定の、TUN / TAP を選択する直下の Network と Netmask の部分がそれである。ここの例では 192.168.11.0/24 としてみた。 ブリッジモードではクライアントはそのままサーバー側のサブネット(192.168.0.0/24 とする)に参加する形となり、VPN サーバーが DHCP サーバーとしてクライアントに IP プールの中から一つ割り当てる形だった。ルーターモードでは、VPN 用のサブネット(192.168.11.0/24)丸ごとが IP プールとなりそれをクライアントに割り当てる。なので、VPN クライアントはサーバー側の本来のサブネットには直接参加しない形となるので、VPN 用のサブネットからサーバー側の本来のサブネットへとアクセスするためのルーティング設定が必要となる。そのために、DD-WRT の Additional Config においてクライアントにプッシュする形でルーティング設定をセットする。 push "redirect-gateway def1 bypass-dhcp" ※ "route 192.168.11.0 255.255.255.0" を別途 push する必要はない。redirect-gateway でリダイレクトされる Gateway 設定に同じ route 情報は含まれている。 さらに、これで VPN サブネット側のクライアントがサーバー側の本来のサブネットにアクセスでき...

ローカルディスク ⇄ NFS ディスク間の rsync

イメージ
👉 前回 で OpenVPN の接続と NFS のマウントまで自動化できたので、あとは特定のフォルダーをローカルディスク ⇄ NFS ディスク間における rsync をボタン一発でできるようにするだけだ。 最新の rsync macOS 標準の rsync はバージョンが旧いので、Homebrew で最新バージョンにするのが常套のようだ。 brew install rsync だけで ok。brew tap してからという情報は既に古いものなので注意。 OS 標準の元から存在する rsync は /usr/bin/rsync に、brew でインストールされた新しい rsync は /usr/local/bin/rsync にある。 ローカルディスク ⇄ NFS ディスク間における rsync 下の例では、~/eclipse-workspace フォルダを丸ごと、NFS にマウントした NAS の共有フォルダにバックアップしている。また、NAS 側で NFS のオプションを ALL_SQUASH で自分のアカウント名に割り当てているため、ファイルの所有者などの情報は rsync 側のオプションで制御していない。rsync 自体の詳しいオプションについては別途詳細を調べて欲しい。また下の例では省略したが、実際には --exclude オプションなども指定して、キャッシュデータは一々バックアップしないように等している。 /usr/local/bin/rsync -ruv --delete ~/eclipse-workspace /Volumes/NFS Automator によるアプリ化 上記 rsync のコマンド内容のシェルスクリプトを Automator を使ってアプリ化する。 Automator の使い方自体については 簡潔な解説 があり参考になる。

VPN 接続(Tunnelblick)と NFS マウントの自動化

👉 先の記事 で sudo がパスワード入力なしで実行できるようになったので、それを前提として VPN 接続に連動して NFS のマウント/アンマウントを自動化する方法を確立した。 (Tunnelblick のベースである)OpenVPN 自体の仕様で .ovpn ファイルの設定で up / down 用のスクリプトを指定できるようになっている。この仕様に加えて、Tunnelblick では、connected.sh と pre-disconnect.sh という名前のスクリプトをそれぞれ up / down 用スクリプトとして割り当てることによって「接続後」「切断前」に実行するスクリプトとし扱ってくれるようだ。 なので、connected.sh と pre-disconnect.sh を用意し、それぞれにおいて、NFS をマウント/切断する処理を記述しておいた。 connected.sh #!/bin/sh sudo mkdir /Volumes/NFS sudo mount_nfs -P 192.168.0.1:/share /Volumes/NFS pre-disconnect.sh #!/bin/sh sudo umount /Volumes/NFS ※ umount 時に /Volumes/NFS は自動的に rmdir されるので、rmdir は明示的に行う必要はない。 以上の 2 種のスクリプトを用意した上で、.ovpn に .ovpn up ~/OpenVPN/connected.sh down ~/OpenVPN/pre-disconnect.sh といったような形式の設定を追加する。 最後に、Tunnelblick で .ovpn をインポートする。これだけである。 ※ .ovpn や .sh を修正した場合、都度 Tunnelblick にインポートし直す必要がある点に注意する。Tunnelblick はインポート時に自前で .ovpn や .sh をコピーしてそれを直接使うので、インポート元の .ovpn や .sh を修正しただけでは Tunnelblick の挙動に反映されない。 Mac から NFS を使ってみた結果…… iCloud ドライブや Google ドライブのような感覚で使いたいと思...