D.

Ramdisk を使う。

MacRamdisk を利用することにした。手順をメモ。

起動時に Ramdisk を生成して初期化するシェルスクリプトを作る。

/Library/Ramdisk/ramdisk.sh を作成する。

# Ramdisk を作る
RAMDISK="$(hdid -nomount ram://1048576)" # 1 ブロック = 512 バイト
diskutil eraseDisk HFS+ ramdisk $RAMDISK
mkdir /Volumes/ramdisk/tmp
chmod 700 /Volumes/ramdisk/tmp
mkdir /Volumes/ramdisk/Caches
chmod 700 /Volumes/ramdisk/Caches

# アクセス日時を記録しない
mount -u -o noatime /

起動時に上記のシェルスクリプトが実行されるように登録する。

/Library/LaunchAgents/com.ramdisk.plist を作成する。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>com.ramdisk</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Library/RamDisk/ramDisk.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>


以下のコマンドを打つとスタートアップに登録される。

sudo launchctl load -w /Library/LaunchAgents/com.ramdisk.plist


あとは以下のように ~/Library/Caches あたりを Ramdisk に乗せると良いだろう。

rm -rf ~/Library/Caches
ln -s /Volumes/ramdisk/Caches ~/Library/Caches

追記 (2012/1/16)

SSDRamdisk を利用する場合は、以下のコマンドでハイバーネートを防止する。

sudo pmset hibernatemode 0
sudo rm /var/vm/sleepimage

プラガブルに拡張可能な zshrc を書きたくなったので、書いた。

zsh は zcompile コマンドにより中間バイトコードをあらかじめ生成し起動の高速化を図ることができる。だが一人で複数ユーザーを利用したりしていると、いちいち各ユーザーごとに zcompile するのがダルイし、どうせなら /etc/zsh あたりに共通のファイルを置きたい。また、ちょっとしたコード片を追加するときに plugins ディレクトリに放り込んでそのまま拡張できる仕組みが欲しい。 .zshrc を編集してもいいのだが、変更部分だけ独立していたほうが管理も楽になるだろう。このあたりの問題解決を目的としている。

目的

  • 中間バイトコードをシェアして zsh の起動を高速化する。
  • プラガブルに .zshrc を拡張できる。 (コード片を plugins ディレクトリに放り込めば即反映)
  • インストール先を指定できる。 (sudo が使えても使えなくても OK)

ソースコード

https://github.com/id774/dot_zsh

インストール方法
cd
git clone git://github.com/id774/dot_zsh.git # リポジトリからチェックアウトする
~/dot_zsh/install_dotzsh.sh # インストーラーを実行
cp ~/dot_zsh/dot_zshrc ~/.zshrc # .zshrc を上書きする (または vim などで切り貼りする)

解説

インストール

基本的には sudo を内部的に利用して /etc/zsh 配下にインストールする。インストーラーである install_dotzsh.sh の第一引数にインストール先を指定することができる。第二引数に nosudo を指定すると sudo を利用しない。

例: ~/.zsh/ 配下にインストールし sudo は利用しない。

~/dot_zsh/install_dotzsh.sh ~/.zsh nosudo
ディレクトリ構成
  • /etc/zsh/lib … 全体をロードしたり screen を起動したりする。ここは基本的にいじらない。
  • /etc/zsh/plugins … システム管理者が .zsh ファイルを追加すれば自動的に読み込み対象となる。


基本的には上記の通り。これ以外に ~/.zsh/lib や ~/.zsh/plugins を利用することもできる。

  • ~/.zsh/lib … 中核となる load.zsh base.zsh screen.zsh をカスタマイズしたいときに使う。ここにディレクトリがある場合 /etc/zsh/lib の下のファイルは読み込まれず、こちらにあるものが利用される。
  • ~/.zsh/plugins … プラグインをユーザーレベルで管理したいときにここに入れる。ここにディレクトリがある場合 /etc/zsh/plugins のプラグインの下のファイルは読み込まれず、こちらにあるものが利用される。
デフォルトの動作
動作確認
参考にしたモノ

世界には oh-my-zsh とかいう異常な zshrc があるのだが、これはちょっとやりすぎ感があるのと、テーマなんてどうせひとつしか使わないのに大量にあるのが無駄な気がしたので、ベースはひとつ、拡張したい部分だけプラグインで上書きして解決する、といった方針にした。思いつきで一日か二日程度で書いてみた。

zsh の自動インクリメンタル補完が素晴らしい件。

これはまさに Life Changing だ。 zsh で自動的にインクリメンタル補完をしてくれる。いままで Tab キーを入力して手動で補完していたのだがそれを自動でやってくれる。


Incremental completion on zsh
http://mimosa-pudica.net/zsh-incremental.html


以下のブログで紹介されている。
http://d.hatena.ne.jp/seiunsky/20110519/1305764493

導入

ダウンロード
curl -O -L http://mimosa-pudica.net/src/incr-0.2.zsh
test -d ~/.zsh/plugin || mkdir -p ~/.zsh/plugin
mv incr-0.2.zsh ~/.zsh/plugin
.zshrc で読み込む
load_plugins() {
    if [ -d ~/.zsh/plugin ]; then
        source ~/.zsh/plugin/*
    fi
}

main() {
    load_plugins
}

課題

試したところ個人的に 2 点気になるところがあった。

エスケープシーケンスがうまく効かない。

環境によってはエスケープシーケンスが効かないようなので、以下のようにパッチを当てた。

85d84
<               echo -n "\e[32m"
91,95d89
< function preexec
< {
<       echo -n "\e[39m"
< }
<
ssh 構文の補完で相手先ホストに大量の接続要求をしてしまう。

たとえば以下のようなコマンドを打つ場合。

rsync -avz hoge user@host:~/Documents/

相手先のホストで一定時間内の ssh の接続回数を制限していた場合などに、コマンドを途中まで打つだけで BAN されてしまう。


これについては回避方法がいまのところ思いつかないので良い案が欲しいところ。

5/22 22:47 追記

以下のように特定のコマンドを自動補完対象外にすることで解決した。

@@ -20,6 +20,7 @@ bindkey -M emacs '^i' expand-or-complete-prefix-incr
 
 unsetopt automenu
 compdef -d scp
+compdef -d rsync
 compdef -d tar
 compdef -d make
 compdef -d java

rails 3.0.x で scaffold する。

もう rails 3.1 beta1 が edge に来ているというのに 3.0 にいまさら移行した。すぐ忘れるのでメモ。

ruby 1.9.2 を入れる。

適当

rubygems を最新化する (しなくても良い)。

gem update --system

rails を入れる。

sudo gem install -v "< 3.1" rails

mysql アダプタを入れる (MySQL を使う場合)。

sudo /opt/bin/gem install -v "< 0.3" mysql2

mysql2 アダプタが必要で、なおかつ 0.3 以上は rails 3.1 用に作られているので、このような入れ方をする。

アプリケーションを新規作成する。

rails new hoge

new というサブコマンドが必要になった。

Gemfile

gem 'rails', '3.0.7'
gem 'mysql2', '0.2.7'

bundle install する。

bundle install

バンドルされた Gems を確認する。

bundle show

config/database.yml

adapter: mysql2

config/application.rb

config.time_zone = 'Tokyo'
...

その他適当に。基本的には従来の config/environments.rb の内容を移行させれば良い。

scaffold して db:migrate する。

rails g scaffold fuga fuga_name:string fuga_id:integer
rake db:migrate:reset

WEBrick を起動する。

rails server -p 3000 -e development


ブラウザを開いてポート 3000 番の fugas にアクセスする。

Git と Subversion を共存させる。

まず最初に Subversion の管理下のファイルをチェックアウトし .git を管理対象外に設定する。

svn propset svn:ignore ".git" .


Git の excludesfile で .svn を指定しておく。

~/.gitconfig

[user]
        email = yourname@gmail.com
        name = yourname
[core]
        excludesfile = /home/yourname/.gitignore


~/.gitignore

(色々)
.svn


あとは Subversion の管理下のディレクトリで git init すれば良い。

git init
git add .
git commit -m "from svn"
git push

svn up または git pull で最新状態に追随できるので、変更点をもう片方の構成管理システムにコミットする。


チームでは Subversion を利用しているけど個人では Git を使いたいときなどに活用できる。他に git-svn を使う手もあるけど、この方法だと commit だけでなくpush する粒度も変えることができるのが利点。

git で複数のリモートリポジトリに一度に push したりする。

git リポジトリの .git/config には remote origin となる URL がテキストで書かれている。

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = ssh://user@host/~user/git-bare/repo.git
[branch "master"]
        remote = origin
        merge = refs/heads/master

なお、これらの値は git config -l で参照することもできる。このうち remote.origin.url を書き換えることで pull/push の対象となるリポジトリを指定することができる。

git で複数のリポジトリに同時に push する。

複数のリモートリポジトリに一度に push したい場合は remote.origin.url を 2 行にすれば良い。

[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = ssh://user@hostA/~user/git-bare/repo.git
        url = ssh://user@hostB/~user/git-bare/repo.git

中継点となる git リポジトリを用意する。

インターネット上のホスト A に公開用の bare リポジトリがある。イントラネット上のホスト B は外部と通信できるが、それ以外のホスト C,D,E は通信できない。このような場合に remote origin を以下のようにすることでホスト B を中継して git pull することができる。

ホスト B

        url = ssh://user@hostA/~user/git-bare/repo.git
        url = ~/git-bare/repo.git

ホスト C,D,E

        url = ssh://user@hostB/~user/git-bare/repo.git

ホスト B はリモートリポジトリ及び自身の公開用 bare リポジトリに対して一度に push すれば良い。

ローカルにある公開用リポジトリから pull する。

前回の記事github から移行した場合 remote.origin.url が github のままになっている。これはローカルの git-bare を参照するようにすれば良い。

<   url = git@github.com:yourname/repo.git
---
>   url = ~/git-bare/repo.git

このように url をサーバーのディレクトリ宛に書き換えれば自身の bare リポジトリから pull できる。

プライベートな git リポジトリを手軽に用意する。

プログラマなら誰しも自分用のプライベートな git リポジトリを持っていることだろう。

いままで自分専用のリポジトリを利用するために github を利用してきた。 github は Web インターフェースを備えており Wiki や Graph などチームで開発をするために有用な機能がある。

しかし githubリポジトリを非公開にするには課金しないといけない。そのためいままで必要に迫られて課金してきたのだが、よく考えると自分専用のサーバー群を格安で持てるこの時代に最低月 7 ドルもリポジトリのためだけにマネーを支払うのはなんとも勿体無い話である。上記のリッチな付加機能も自分一人で利用するならほとんど必要無い。

そこで自分のサーバーに git のリポジトリを用意することにした。セキュアにしたいので通信プロトコルssh を利用することにする。そのやり方をメモしたので公開する。

新しく公開用の git リポジトリを作成する場合。

mkdir -p ~/git-bare/repo # 公開場所はサーバーの ~/git-bare/repo.git とする
cd ~/git-bare/repo
git init # リポジトリを初期化する
touch readme.txt
git add readme.txt
git commit -m "first commit" # 何でも良いからとにかくコミットする
cd ..
git clone --bare repo repo.git # repo リポジトリから公開用の bare リポジトリを生成する

git は空のリポジトリであってはならず、最初に必ず何かをコミットしておく必要がある。
上記の例では readme.txt を初期ファイルとしている。

既存の githubリポジトリから移行する場合。

mkdir -p ~/git-bare
cd ~/git-bare
git clone git@github.com:yourname/repo.git # github からクローンを生成する
git clone --bare repo repo.git # github のクローンからさらに公開用の bare リポジトリを生成する


この時点で ~/git-bare には repo と repo.git というディレクトリが存在する。このうち repo.git が bare リポジトリとなる。これは公開用のものであり repo のファイル自体は含まない。

利用してみる。

ではさっそく他のマシンから上記のリポジトリにアクセスできるか試してみる。ここからはローカルで作業する。

git clone ssh://yourname@hostname/~yourname/git-bare/repo.git

これでローカルにリポジトリの内容を取得できれば成功である。


さらに確認のためローカルで変更をし、それをサーバーのリポジトリに反映してみる。

cd repo
touch hoge.txt
git add hoge.txt
git commit -m "test"
git push

これで無事に push されれば成功である。あとは思う存分コードを書いてコミットしまくれば良い。

万全を期すなら、ローカルのリポジトリを一旦削除し再度 git clone してみて push した内容も含めて取得できることを確認しておこう。