HTML の構造を YAML で吐き出すスクリプトを書いた
pixiv の HTML がどんどん変わって pixiv gem が追従できなくて困った。ので楽するやつを書いた。 HTML を読み込ませると要素の親子関係と各要素の属性を YAML にして書き出す。テキストノード他は無視する。 XPath か CSS Selector で不要な要素を取り除くことができる。
!omap
で書き出してあるから map の順序が固定されていて diff しやすい。 pixiv の画像一覧ページなどを定期的に取得して HTML で保存しておき、最新の2つから広告やワンタイムトークンを削除しつつ YAML 化して差分を取る。で構造に変化があれば対応する。テストも自動化したいけどそれはいずれ。
使い方:
html2yaml.rb [-x, --exclude=<xpath or css>] \ [-i, --include=<xpath or css>] \ <URL or path>
--exclude
と --include
は複数回指定でき、書いた順に適用される。 --exclude
はマッチした要素とその子孫要素を出力から取り除く。 --include
はマッチした要素とその祖先要素を出力に含める。
コード:
出力例:
html2yaml.rb -x "*" -i div "http://www.google.com" | head -n20
--- !omap - :name: html - :attributes: !omap - itemscope: '' - itemtype: http://schema.org/WebPage - :children: - !omap - :name: body - :attributes: !omap - bgcolor: '#fff' - lang: ja - :children: - !omap - :name: div - :attributes: !omap - id: mngb - :children: - !omap - :name: div - :attributes: !omap
Raspberry Pi の Arch Linux にスワップを設定して Ruby をビルドする
何も考えずに rbenv install 2.0.0-p247
で Ruby をビルドしたところ、メモリ不足でプロセスが kill されてしまった。もともとメモリが512MBしかないうえに tmpfs がその半分を利用し、デフォルトではスワップ領域も設定されていないので、大きなアプリケーションのビルドは厳しいようだ。
そこでスワップファイルをスワップ領域として使うように設定する(参考:Swap (日本語) - ArchWiki):
# スワップ領域が設定されていないことを確認する # 何も出力されなければ OK $ swapon -s # 空のスワップファイルを作る # dd でもいいが fallocate を使うほうが速い $ sudo fallocate -l 1G /var/swapfile # スワップファイルをフォーマットする $ sudo mkswap /var/swapfile # スワップ領域を有効にする $ sudo swapon /var/swapfile # スワップ領域が設定されたことを確認する $ swapon -s Filename Type Size Used Priority /var/swapfile file 1048572 0 -1 # 起動時にスワップ領域をマウントするよう /etc/fstab に設定を追加する $ sudo sh -c 'echo "/var/swapfile none swap defaults 0 0" >> /etc/fstab'
これでスワップ領域を設定できた。ついでに /tmp ディレクトリのサイズも拡張してしまおう。
/tmp ディレクトリは tmpfs によってメモリ上に確保されており、デフォルトでは実メモリの半分の容量がディレクトリサイズの上限となっている(RaspberryPi ModelB では230MB程度)。 /tmp は systemd が自動的にマウントするので、 systemd の設定ファイルを追加してマウント時にサイズを指定してやればよい(参考:systemd (日本語) - ArchWiki):
# デフォルトのマウント設定ファイルは /usr/lib/systemd/system/tmp.mount # この一部を上書きする設定ファイルを以下のディレクトリに入れる $ sudo mkdir -p /etc/systemd/system/tmp.mount.d $ cd /etc/systemd/system/tmp.mount.d # デフォルトのオプションに `size=1G` を追加したものを *.conf に保存する # ここでは increase-size.conf とした $ sudo sh -c 'echo "[Mount]\nOptions=mode=1777,strictatime,size=1G" >> increase-size.conf' # 設定をリロードする $ sudo systemctl --system daemon-reload # 追加した設定ファイルがロードされたか確認する $ systemctl status tmp.mount tmp.mount - Temporary Directory Loaded: loaded (/usr/lib/systemd/system/tmp.mount; static) Drop-In: /etc/systemd/system/tmp.mount.d └─increase-size.conf # ←これがあれば OK (後略) # /tmp を再マウントする $ sudo systemctl restart tmp.mount # 追加した設定を使ってマウントが行われたか確認する $ systemctl status tmp.mount (中略) Process: 3014 ExecRemount=/bin/mount tmpfs /tmp -t tmpfs -o remount,mode=1777,strictatime,size=1G (code=exited, status=0/SUCCESS) # ↑size=1G が反映されていれば OK # /tmp ディレクトリのサイズを確認する $ df -h (中略) tmpfs 1.0G 0 1.0G 0% /tmp # ←1.0Gになっていれば OK
これで Ruby をビルドする準備が整った。
$ rbenv install 2.0.0-p247
数時間かかるので気長に待つ。
DDNS サービスを利用して外出先から Raspberry Pi に SSH する
前の記事でセットアップした Raspberry Pi に外出先からログインできるようにしてみる。
まず NoIP でフリーのアカウントを作る。メールアドレスとパスワードと割り当てられたドメインをメモしておく。
Raspberry Pi に ddclient をインストールする:
$ yaourt -S ddclient
/etc/ddclient/ddclient.conf に設定を記述する:
daemon=300 # 300秒ごとに IP をチェック syslog=yes # syslog にログを出力 mail-failure=your-mail@example.com # 更新失敗時にメール送信 pid=/var/run/ddclient.pid # プロセスの PID ファイル ssl=yes # SSL を有効にする ## ## NoIP ## # DNSPark の web ページを使って自身のグローバル IP をチェック use=web, web=ipdetect.dnspark.com, web-skip='Current Address:' # NoIP のアカウント設定 protocol=noip, \ login=your-mail@example.com \ password=YOUR_PASSWORD_HERE \ your-host.no-ip.biz
ddclient サービスを起動する:
$ systemctl enable ddclient $ systemctl start ddclient
ルータの設定で外部の22番ポートを Raspberry Pi の22番ポートにマップする。
これで外出先から ssh your-host.no-ip.biz
で Raspberry Pi に接続できるようになった。
Mac で Raspberry Pi 用の Arch Linux を準備してみた
はじめに
本稿では Mac を使って Raspberry Pi 用に Arch Linux をセットアップする手順を説明する。今回構築する Linux システムでは、ルートファイルシステムを外付けハードディスクに移し、ブートファイルシステムを収めた SD カードを読み取り専用で扱うことを目指す。 Arch Linux の初期設定についてはカバーしない。また本稿は備忘録であるため内容の正確さは保証しない。内容についての指摘は歓迎する。
用意した環境
- Arch Linux ARM (archlinux-hf-2013-07-22.img)
- MacBook Pro 15-inch, mid 2010
- Raspberry Pi ModelB 512MB
- 適当な SD カード(8GB)
- 適当な USB 接続の外付けハードディスク(120GB)
- 5V700mA 以上で MicroUSB 出力できる電源(100円ショップにあるスマホ用充電ケーブルで十分)
- 接続に必要なもの
- USB キーボード
- HDMI ケーブルとテレビ
- 上記2つ、または LAN ケーブル
SD カードをフォーマットする
SD カードを Mac の SD カードスロットに挿入する。/アプリケーション/ユーティリティ/ディスクユーティリティを起動し、左の欄から「xxGB APPLE SD Card Reader Media」を選択する。右のタブの「消去」を選び、フォーマット:「MS-DOS (FAT)」、名前:「UNTITLED」になっていることを確認し、「消去…」ボタンを押す。
SD カードをアンマウントする
ターミナルを起動し、マウントされている SD カードを df
コマンドで確認する:
$ df Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted on /dev/disk0s2 659597488 588953464 70132024 90% 73683181 8766503 89% / (中略) /dev/disk3s1 15681728 4288 15677440 1% 0 0 100% /Volumes/UNTITLED
/Volumes/UNTITLED としてマウントされている SD カード(の第1パーティション)は、 /dev/disk3s1 というデバイスであることが分かる。この値は環境によって異なるかもしれないので、その場合は以降の記述を適宜読み替えてほしい。
diskutil
コマンドでこの SD カードをアンマウントする:
$ diskutil unmount /dev/disk3s1 Volume UNTITLED on disk3s1 unmounted
SD カードに OS のディスクイメージを書き込む
Raspberry Pi 向けの ArchLinux ARM のページの Installation タブを開き、 OS のディスクイメージをダウンロードする。ダウンロード ZIP ファイルを展開すると archlinux-hf-2013-07-22.img が作られる。このディスクイメージを dd
コマンドで SD カードに書き込む:
$ sudo dd bs=1m if=/path/to/archlinux-hf-2013-07-22.img of=/dev/rdisk3 1870+0 records in 1870+0 records out 1960837120 bytes transferred in 201.702728 secs (9721421 bytes/sec)
of=/dev/rdisk3
は先ほど確認したデバイス名に合わせて読み替える(デバイス名が /dev/disk4s1 なら of=/dev/rdisk4
という具合)。
補足: Mac の BSD dd では bs オプションの数字の接尾辞を小文字にしなければならない。一方 GNU dd の bs オプションは接尾辞が大文字である。
書き込みが終わるとふたたび SD カードがマウントされるので、ファインダーを操作して SD カードを取り出す。
Raspberry Pi を起動する
Raspberry Pi に SD カードを挿入し、外付けハードディスクを基板から遠いほうの USB ポートに接続する(ポートの位置は重要ではないが、以降の説明に現れるハードディスクのデバイス名が変わってくるかもしれない)。外付けハードディスクが外部給電タイプではない場合、 Raspberry Pi との間にセルフパワード USB ハブを挟むこと。そうしなければ Raspberry Pi の電源が不安定になり、起動しなかったり突然落ちたりする。
空いている USB ポートにキーボードを接続し、 HDMI ポートにはテレビを繋ぐ。それらの代わりに、 LAN ケーブルで Raspberry Pi とルータを接続し、起動後に SSH でログインすることもできる。 この手順は詳しく解説しない。
電源ケーブルを除く各ケーブルの接続が終わったら、外付けハードディスクの電源を入れ数秒待つ。電源を安定させる意図でこのようにしたが、こうする必要はないかもしれない。
最後に Raspberry Pi の電源ケーブルを接続する。基板の PWR ランプが点灯し、テレビ画面に起動ログが出力されれば起動成功である。
外付けハードディスクをフォーマットする
ユーザ名「root」、パスワード「root」で Raspberry Pi にログインする。外付けハードディスクに対応するデバイス名を lsblk
コマンドで調べる:
[root@alarmpi ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 111.8G 0 disk `-sda1 8:1 0 111.8G 0 part mmcblk0 179:0 0 7.5G 0 disk |-mmcblk0p1 179:1 0 90M 0 part /boot |-mmcblk0p2 179:2 0 1K 0 part `-mmcblk0p5 179:5 0 1.7G 0 part /
ディスクのデバイス名は /dev/sda、その第1パーティションは /dev/sda1 であることが分かる。ルートファイルシステムにあたる SD カードのパーティションが /dev/mmcblk0p5 であることもメモしておく。
fdisk
コマンドでディスクをフォーマットする。すべてのパーティションを削除し、プライマリパーティションを1つ作成する:
[root@alarmpi ~]# fdisk /dev/sda Command (m for help): d # パーティション削除:すべて削除するまで繰り返す Command (m for help): n # パーティション作成:質問はすべてデフォルト値でよい Command (m for help): w # 情報をディスクに書き込んで終了
ルートファイルシステムを外付けハードディスクに移す
SD カードの書き換え回数には上限があるため、なるべく書き込みを減らしたいものである。そこで、ルートファイルシステムを丸ごと外付けハードディスクに移してしまうことにする。
まずルートファイルシステムを SD カードから外付けハードディスクにコピーする:
[root@alarmpi ~]# dd bs=1M if=/dev/mmcblk0p5 of=/dev/sda1
if オプションの値は先ほどメモした SD カードのパーティションにすること。
コピーされたルートパーティションのファイルシステムは ext4、サイズは2GBになっている。サイズが小さいままではもったいないなので、パーティションをハードディスク全体に拡張する。パーティションのリサイズには resize2fs
コマンドを使う:
[root@alarmpi ~]# resize2fs /dev/sda1
特にオプションを与えなければパーティションを最大まで拡張してくれる。
補足:各デバイスのファイルシステムは lsblk -f
で一覧できる。
外付けハードディスク内のルートファイルシステムで起動する
起動時に外付けハードディスク内のルートファイルシステムを参照するように、起動パラメータを書き換える:
[root@alarmpi ~]# vi /boot/cmdline.txt ipv6.disable=1 selinux=0 plymouth.enable=0 smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p5 rootfstype=ext4 elevator=noop rootwait
/boot/cmdline.txt 内の root=/dev/mmcblk0p5
を root=/dev/sda1
に修正し、保存する。
reboot
コマンドで再起動し、 lsblk
コマンドでデバイスを確認する。 sda1 のマウントポイントが /
になっていればよい。
[root@alarmpi ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 111.8G 0 disk `-sda1 8:1 0 111.8G 0 part / # ←こうなっていれば成功 mmcblk0 179:0 0 7.5G 0 disk |-mmcblk0p1 179:1 0 90M 0 part /boot |-mmcblk0p2 179:2 0 1K 0 part `-mmcblk0p5 179:5 0 1.7G 0 part
パラメータを間違えるなどして Raspberry Pi が起動しなくなった場合、 SD カードを Mac に挿入してファインダーで開き cmdline.txt を編集するとよい。
終わりに
これで目指したとおりの環境が構築できた。この構成ならば基本的には SD カードにデータが書き込まれることはないため、書き込みプロテクトスイッチをオンにしてもよいかもしれない。
参考にしたページ
- RaspberryPiの焼き方(MacからArchLinuxインストール) | hello-world.jp.net - SD カード作成から初期設定まで。簡潔にまとまっている。
- トマト農家のロボット創り Robot creation by tomato farmer: Raspberry Pi に Arch Linux ( archlinux-hf-2013-07-22 ) を インストールする - 同じく SD カード作成から初期設定まで。詳細に記述されており、ためになる。
- fdiskでフォーマットする - Android on Beagle
- Ext4 Howto - Ext4
- 6.3. ext4 ファイルシステムのサイズを変更する - Red Hat Customer Portal
- ext4 へのマイグレーション
- No caching mode page present / Assuming drive cache:write through (Page 1) / Kernel & Hardware / Arch Linux Forums
unionfs-fuse か aufs でルートファイルシステムをオーバーレイすることも考えたが面倒そうだったのでやめた。そのときの調査記録も残しておく:
- Raspberry Pi (の4):半歩先:So-netブログ - unionfs-fuse の使い方。 initd を前提にしているので Arch Linux には適用できなかった。
- systemd (日本語) - ArchWiki
できたばかりの web サービスを知るには LaunchRock Discover がよい
LaunchRock Discover にメールアドレスを登録すると、数週間に一度、ローンチしたばかりの、またはこれからローンチする web サービスのまとめが送られてくる。
ローンチ前の web サービスの情報をどうやって集めてくるのか不思議に思えるが、これは LaunchRock の本業に秘密がある。 LaunchRock は「ローンチのためのプラットフォーム」を提供している。公開前の web サービスを宣伝したい開発者は、 LaunchRock を使ってサービスの告知ページを簡単に作ることができる。また告知ページのアクセス解析や優先招待システムなどローンチに関わる様々なツールも利用できる。 LaunchRock Discover は宣伝の一環としてそれら公開前のサービスのまとめを配信するという仕組み。
最近サインアップした web サービス
便利そうなものをメモっておく。
- Quip:オンラインワードプロセッサ。Web アプリ・iOS デバイス・Android デバイスからドキュメントを編集できる。
- Handle:Gmail のフロントエンドにタスク管理システムを統合した web アプリ。
- App.net:フリーミアムモデルのソーシャルネットワーキングプラットフォーム。金を払って使う Twitter のようなもの。
Quip について
Google Docs よりも編集インターフェースがクリーン。本格的なワードプロセッサアプリと比較すると文書の装飾の自由度は劣るが、シンプルで見栄えのいいドキュメントを書くにはむしろほどよい制限になっている。コラボレーション機能を備えており、複数人でひとつのドキュメントを編集できるほか、各人の編集履歴やドキュメントごとに設けられたコメント欄のログがタイムラインに一覧表示される。 Evernote のように個人的なメモ用途として使うこともできるが、それよりは一人〜複数人である程度の規模の文書を作るときに使うとよさそう。
Handle について
Gmail の Inbox をざくざく読みながら必要なものだけタスクリストに積む、といった使い方に特化している。ほとんどの操作をキーボードショートカットで実行できるようになっており、発展途上ながらおおむね Gmail のキーボードショートカットより優れていると感じる。 Inbox にあるはずのメールが読み込まれないなど、まだまだ不安定な部分も多い。 iPhone アプリもあるがメールの閲覧はできず、タスク化したアイテムを表示できるのみ。そしてすぐ落ちる。コンセプトと操作感には強く期待できるので安定したら常用したい。
2013年8月24日現在で招待制のベータ版。 Handle のブログから招待コードを入手するとすぐにサインアップできる。