chkconfigの使い方
chkconfigは/etc/init.dに登録されたサービスの自動起動を管理するコマンド。
なんどやっても覚えないのでまとめとく。
サービスの一覧
登録されているサービスを表示するには--listを指定する。(と言っても省略可)
サービス毎にどのランレベルで起動するかを示している。
$ chkconfig --list # もしくはchkconfig NetworkManager 0:off 1:off 2:on 3:on 4:on 5:on 6:off abrtd 0:off 1:off 2:off 3:on 4:off 5:on 6:off atd 0:off 1:off 2:off 3:on 4:on 5:on 6:off auditd 0:off 1:off 2:on 3:on 4:on 5:on 6:off avahi-daemon 0:off 1:off 2:off 3:on 4:on 5:on 6:off bluetooth 0:off 1:off 2:off 3:on 4:on 5:on 6:off cpuspeed 0:off 1:on 2:on 3:on 4:on 5:on 6:off …
サービス名を指定すれば、そのサービスだけ表示できる。(この場合--listは必須)
$ chkconfig --list crond crond 0:off 1:off 2:on 3:on 4:on 5:on 6:off
サービスの自動起動を変更
sshdサービスの自動起動をON
# chkconfig sshd on
レベルを指定してONにする場合は
# chkconfig --level 35 sshd on # ランレベルが3か5の場合に起動する
sshdサービスの自動起動をOFF
# chkconfig sshd off
サービスの追加・削除
パッケージを利用してると、大抵は追加されているので実行したことないけど
自動起動するサービスを追加・削除できる。
sshdサービスを追加
# chkconfig --add sshd
sshdサービスを削除
# chkconfig --del sshd
ちなみに
ランレベル毎にサービスを起動するかどうかは、/etc/rc(ランレベル).d/以下のシンボリックリンクで決まる。
$ ls -l /etc/rc*.d/*crond lrwxrwxrwx. 1 root root 15 2010-04-20 02:08 /etc/rc0.d/K60crond -> ../init.d/crond* lrwxrwxrwx. 1 root root 15 2010-04-20 02:08 /etc/rc1.d/K60crond -> ../init.d/crond* lrwxrwxrwx. 1 root root 15 2010-04-20 02:08 /etc/rc2.d/S90crond -> ../init.d/crond* lrwxrwxrwx. 1 root root 15 2010-04-20 02:08 /etc/rc3.d/S90crond -> ../init.d/crond* lrwxrwxrwx. 1 root root 15 2010-04-20 02:08 /etc/rc4.d/S90crond -> ../init.d/crond* lrwxrwxrwx. 1 root root 15 2010-04-20 02:08 /etc/rc5.d/S90crond -> ../init.d/crond* lrwxrwxrwx. 1 root root 15 2010-04-20 02:08 /etc/rc6.d/K60crond -> ../init.d/crond*
chkconfigはこのシンボリックリンクを編集しているようだ。
Kで始まるシンボリックリンクがOFFで、Sで始まるのがONってことね。
Snow LeopardにしたらMacPortsが動かなくなった
Snow Leopardにしてからportコマンドエラーが出るようになった。
dlopen(/Library/Tcl/macports1.0/MacPorts.dylib, 10): no suitable image found. Did find: /Library/Tcl/macports1.0/MacPorts.dylib: mach-o, but wrong architecture while executing "load /Library/Tcl/macports1.0/MacPorts.dylib" ("package ifneeded macports 1.0" script) invoked from within "package require macports" (file "/opt/local/bin/port" line 39)
もともとMacPortsは、単一のOS・CPUで動作するように設計されており、OSやCPUが変わると再インストールが必要なようだ。
http://trac.macports.org/wiki/Migrationに移行方法が書かれていたので実践してみる。
Portsを再インストール
まずはSnow Leopard版のXcodeが必要なのでインストールディスクからインストールしておく。
次にSnow Leopard版のMacPortsをhttp://www.macports.org/install.php
から最新のdmgをダウンロードし、インストールし直す。 (現時点で最新は1.9.2)
続いてインストール済みリストを書き出す。
$ port installed > myports.txt
インストール済みのポートをすべてアンインストール。
$ sudo port -f uninstall installed
ビルドやアーカイブを削除。
$ sudo port clean --work --archive all
最後に、myports.txを見ながら適切なvariantを設定しつつ、1つずつインストールする。
$ sudo port install portname +variant1 +variant2 ...
1つずつインストールする…。
…。
いやいや、めんどくさい。
201個もあるんだよ、ムリムリ。
自動再インストール
幸い実験的ではあるけど、自動インストールスクリプトrestore_ports.tclが用意されている。
次のコマンドでダウンロード・実行可能にする。
$ curl -O http://svn.macports.org/repository/macports/contrib/restore_ports/restore_ports.tcl $ chmod +x restore_ports.tcl
以前にインストールしていたポートのリスト(myports.txt)を指定して実行。
$ sudo ./restore_ports.tcl myports.txt
そのままでは恐らく次のようなエラーが出るので
couldn't read file "/Library/Tcl/macports1.0/macports_fastload.tcl": no such file or directory while executing "source ${macportsTclPath}/macports1.0/macports_fastload.tcl" (file "./restore_ports.tcl" line 244)
-tでtclのパスを指定してあげる。
$ sudo ./restore_ports.tcl -t /opt/local/share/macports/Tcl myports.txt
あとは自動的にイントールしてくれるので、基本的には待つだけ。
エラーがでた場合
依存関係によっては、ポートをdeactivateできなくてエラーがでることも。
---> Deactivating p5-compress-raw-zlib ---> Unable to uninstall/deactivate p5-compress-raw-zlib @2.027_0, the following ports depend on it: ---> p5-io-compress @2.027_0 port deactivate failed: Please uninstall the ports that depend on p5-compress-raw-zlib first. while executing "install_ports $operationList" (file "./restore_ports.tcl" line 264)
この場合は、dependentsで依存しているポートを調べて
$ port dependents p5-compress-raw-zlib
uninstallしてみる。
$ sudo port uninstall p5-io-compress
再度、restore_ports.tclを実行すればOK。
終わりに
restore_ports.tclは一気にインストールするため、かなりの時間がかかる。
再インストールのリスト(myports.txt)は実行前に整理して、不要なポートは削っておくといいと思う。
ただ、ここまで書いといてなんだけど、かなりの確立でエラーが発生するので
ポートの数が少ないなら個別にインストールしたほうが簡単かもしれない。
.ssh/configでサーバを踏み台にする方法
はじめに
ログインしたいサーバが直接公開されておらず、別のサーバを経由しないとログインできないことがある。
そんな時はProxyCommandが便利。
やり方
~/.ssh/configに次のように記述してみよう。
Host honmei-host ProxyCommand ssh fumidai-host nc %h %p HostName 192.168.11.7
honmei-hostが最終的に接続したいホスト。
ProxyCommandのfumidai-hostには経由したいホストを指定する。
HostNameには、fumidai-hostから見えるhonmei-hostへのIPアドレスを指定する。ポートを指定する場合も同様に。
※ただし、fumidai-hostにはncコマンドが必要。大抵入ってるみたいだけど。
後はいつも通りhonmei-hostにアクセス。
ssh honmei-host
すると、まずfumidai-hostへのパスワードを、続いてhonmei-hostへのパスワードを訊かれるようになる。
それぞれ認証が通れば無事ログインできるよ。
vimshellが便利過ぎる件
vimshellとは?
vimshellはVimからシェルを起動するVimScript。
ただ起動するだけなら:!コマンドでも足りるけど、こちらは非同期に処理できないので、実行中はVimでコードを書けないとか欠点が多い。
vimshellなら非同期なシェルが使えるし、色分け・補完もきく。
インタプリタを立ち上げれば、コードを書きつつ評価させることもできるよ、Emacsみたいにね!
インストール
http://github.com/Shougo/vimshell からソースをダウンロード。
解凍したファイルを~/.vim以下に保存。
あと同作者さんのvimprocが必要なので
https://github.com/Shougo/vimproc からソースをダウンロード。
こちらは~/.vim以下に保存するだけではダメで、Linuxではコンパイルする必要がある。
Linuxでは、次のコマンドを実行。
make -f make_gcc.mak
コンパイルが通ったら、autoload/にあるファイルやディレクトリを~/.vimのautoloadディ
レクトリにコピーする。たぶん、proc.so・vimproc.vim・vimproc/だけ保存すればいいと思う。
Vimからシェルを起動する
シェルを起動するには、次のコマンドを実行するだけ、簡単。
:VimShell
シェル上では挿入モードでコマンド実行できる。
lsとかcdとか一般的なコマンドは普通に使える。(なんかたまに警告でるけど)
あと、pythonのようなインタプリタはそのままでは起動できないようだ。
実行するには、直接インタプリタを呼ばずiexeをかますせばOK。
iexe python
インタプリタを起動して対話的にコードを評価させる (Emacsみたいに)
単純にシェルを実行するだけなら:VimShellで十分。
でも別ウィンドウで書いたコードをシェルに評価させる場合は、:VimShellInteractiveを使う。
引数に起動したいインタプリタを指定しよう。
:VimShellInteractive python
すると、左がインタプリタで、右がコードを書くウィンドウが表示される。
では右のウィンドウでコードを書いてみよう。
書き上がったら、選択してから次のコマンドを実行。
:VimShellSendString
すると、左のインタプリタに選択してたコードが渡り評価されるよ。
こんな感じで、ちょこちょこコードを書いては評価してを繰り返すことができる。
ワンライナーで書けないコードを試すには最高だね♪
最後に
毎回コマンドを入力するのは面倒なので、~/.vimrcにショートカットを登録しておくべし。
" ,is: シェルを起動 nnoremap <silent> ,is :VimShell<CR> " ,ipy: pythonを非同期で起動 nnoremap <silent> ,ipy :VimShellInteractive python<CR> " ,irb: irbを非同期で起動 nnoremap <silent> ,irb :VimShellInteractive irb<CR> " ,ss: 非同期で開いたインタプリタに現在の行を評価させる vmap <silent> ,ss :VimShellSendString<CR> " 選択中に,ss: 非同期で開いたインタプリタに選択行を評価させる nnoremap <silent> ,ss <S-v>:VimShellSendString<CR>
いやぁ、もうvimshell最高♪
SQLAlchemyでカラムの値を遅延ロードする方法
どんなO/Rマッパでもそうだと思うけど、モデルを取得すると基本的に全てのカラムから値を取り出そうとする。
1レコードのサイズが少なければ問題にならないが、BLOBのようにサイズの大きなカラムを追加するととたんにパフォーマンスが悪くなってしまう。
SQLAlchemyもそのあたりは同じ。
でもどのカラムが必要で不要なのか細かく指示できるので、うまく調節すれば取り出す値を最小限にとどめることができる。
適用例
userテーブルはBLOB型のiconカラムを持っている。
# テーブル定義 user_table = sqlalchemy.Table( 'user', meta_data, sqlalchemy.Column('id', sqlalchemy.Integer, sqlalchemy.Sequence('user_id_seq'), primary_key = True), sqlalchemy.Column('name', sqlalchemy.Unicode(32), nullable = False), sqlalchemy.Column('icon', sqlalchemy.BLOB, nullable = False)) # マッピング定義 sqlalchemy.orm.mapper(User, user_table, properties = { # ここのdeferred()で遅延ロードを指定している 'icon': sqlalchemy.orm.deferred(user_table.c.icon) })
deferred()を利用することで、iconプロパティは参照されるまでロードしなくなる。
users = db_session.query(User).all() # id、nameはロードされるがiconはロードされない for user in users: user.id # idはすでにロードされている user.icon # ここでようやくiconをロード
実行されるSQLの比較
deferredなし
SELECT "user".id AS user_id, "user".name AS user_name, "user".icon AS user_icon FROM "user"
当たり前だけどiconをロードしてる。
deferredあり
SELECT "user".id AS user_id, "user".name AS user_name FROM "user"
おぉ、ちゃんとiconだけ除外されてる!
問い合わせ時に遅延するか決める
iconのデータも利用することが分かっているのなら、遅延させずに取ってきたいこともある。
そんな時はQuery.options()を使おう。
undefer()を設定すれば、その問い合わせに限り遅延しなくなる。
from sqlalchemy.orm import undefer query = query.options(undefer('icon'))
逆に普段は遅延しない(deferred()なし)のに、今回だけ遅延させたい場合はdefer()を設定する。
from sqlalchemy.orm import defer query = query.options(defer('icon'))
まとめ
O/RマッパはSQLを隠蔽できて便利な反面、どんなSQLが実行されるのか意識しづらい。
知らないうちに非効率なSQLになっていることがあるので注意が必要だ。
幸いSQLAlchemyには、deferred以外にもいろいろチューニングできそうなのでもっと調べていきたい。
というわけで、BLOBのようにサイズの大きなカラムはdeferredしましょう、というお話でした。
参考: http://www.sqlalchemy.org/docs/05/reference/orm/mapping.html#sqlalchemy.orm.deferred
Gitのリポジトリからファイルをエクスポート
svn exportみたいに、ファイルをエクスポートする機能を見つけたのでメモメモ。
例:
$ git checkout-index -a -f --prefix=export/
- -a
- 履歴管理されているすべてのファイルをエクスポート。省略した場合は明示的にファイルを指定する
- 例) $ git checkout-index -prefix=export/ ファイル1 ファイル2 ...
- -f
- エクスポート先に同名のファイルが存在する場合は上書きする
- --prefix
- エクスポート先
--prefixを指定する場合は、末尾に'/'を付けないと悲惨なことになるので要注意。
次のコマンドの場合
$ git checkout-index --prefix=.merged- Makefile
.merged-/Makefileではなく、.merged-Makefileという名前でエクスポートしてしまう。
最初もろに引っ掛かってびっくりしたw。
あまりこの動作を期待することって少ないと思うけど、需要があるってことなのかなぁ。
MacのDNSを設定
ハマったのでメモメモ。
Macに自前のDNSを設定しようと、/etc/resolv.confにnameserverを追加してみた。
nameserver 172.16.232.131
でも一向に反映されない。digで調べても以前のDNSに問い合わせている。
ネットで調べたところ、Macのresolv.confは仮初めのもので、内部で管理している結果をはき出しているだけみたい。
で、本当に設定するには、「システム環境設定」->「ネットワーク」を開き
DNSサーバの欄に、IPアドレスをカンマ区切りで入れて「適用」を押せばOK。
えらい簡単だ♪
以下は、DNS関連のちょっとしたTips。
特定のドメインだけDNSを切り替える方法
参考:MacOS X でドメイン毎にDNSサーバを切り替える | 胡桃ヶ谷
Macの/etc/resolver以下に、DNSを変更したいドメインと同名のファイルを作成する。
(/etc/resolverディレクトリが存在しない場合は作成する)
中の書式はresolv.confと同じで、問い合わせたいDNSを指定できる。
# mkdir /etc/resolver/ # echo nameserver 192.168.1.1 > /etc/resolver/localnet.intra
この場合、localnet.intraにアクセスすると192.168.1.1のDNSに問い合わせるようになるよ。
DNSのキャッシュをクリアする
参考:試験管のなかのコード :: Mac OS X で DNS キャッシュのクリア
DNSの問い合わせ結果は内部でキャッシュされるため、変更してもすぐに反映されないことがある。
Leopard以降は、次のコマンドでキャッシュをクリアできる。
$ dscacheutil -flushcache