hideden.hatenablog.com

はてなぶろぐー。URLなげー。

emacs + trampで多段SSHで接続したサーバー上のファイルを直接編集する時のメモ

会社のサービスはローカルに開発環境を構築するにはでかすぎてだるいので開発サーバー上で開発してるのだが、この開発サーバーが非力すぎて誰かがsvn操作とかでdisk IO使い出すとemacsまで巻き込んで固まる。。。

で、周りの人に聞いてみたらemacs+trampでやってる人が居た。昔チラッと使った時はFUSEのsshfsでマウントした方が何かと便利じゃね?っと思ってすぐ使うのを辞めた気がするので忘れてた。せっかく教えてもらったので真似してみる。

ローカルの環境はOSX Leopardで、ターミナル上のemacs使用。trampはMacPortsとかに無いっぽいので自前で入れる事にした。
trampの現在の最新版は2.1.14。ここから落とした。

wget http://ftp.gnu.org/gnu/tramp/tramp-2.1.14.tar.gz
tar zxf tramp-2.1.14.tar.gz
cd tramp-2.1.14
./configure --with-lispdir=~/.lisp
make
make install

とかで~/.lispにInstall。

.emacs

;; tramp
(require 'tramp)
(setq tramp-default-method "ssh")

って書いて終わり。あとは C-x C-f /my.server.example:~/hoge.txt とかやるとmy.server.exampleに接続して直接ファイルを編集できる。とっても便利。




会社の開発サーバーへは直接接続できず、いくつか踏み台を経由して接続している。仮に下のような感じとする。

localPC -> GW1 server (gw1) -> GW2 server (gw2) -> dev server (hoge.dev)

MacFUSEのsshfsを使ってマウントするのも踏み台を経由すると結構めんどくさくてやってなかったんだが、trumpはその辺賢いらしく踏み台経由の編集が出来るらしい。ググったところ、/multi:ssh:GW1.server:ssh:GW2.server:ssh:dev.server:/tmp/hoge.txtとかやれって記述とかtramp-multi-connection-function-alistをごにょごにょみたいなのを見つけたんだが、どうやらこれは古くて最新版じゃ方法が違うらしい。和訳マニュアルも古いままのようだ。

上の構成の場合はとりあえずこんな感じでやれた。

; *.devに接続するにはgw2を経由する。gw2にはuser: dev001でログインする。
(add-to-list 'tramp-default-proxies-alist
             '("\\.dev" nil "/ssh:dev001@gw2:"))
; gw2に接続するにはgw1を経由する。user: hideden。
(add-to-list 'tramp-default-proxies-alist
             '("gw2" nil "/ssh:hideden@gw1:"))

この設定をした後、C-x C-f /hoge.dev:/tmp/hoge.txt とやると local -> gw1 -> gw2 -> hoge.devとちゃんとたどってくれた。とっても便利。

途中でsudoを挟む場合は以下。

;;途中でsudoする場合
;; hideden@local -> ssh hideden@gw1 -> sudo ssh root@gw2 -> ssh root@hoge.dev

; *.devに接続するにはgw2のrootでなきゃだめ  
(add-to-list 'tramp-default-proxies-alist
             '("\\.dev" nil "/ssh:root@gw2:"))
; gw2に接続するにはgw1でsudoしなきゃだめ
(add-to-list 'tramp-default-proxies-alist
             '("gw2" nil "/sudo:gw1:"))
; gw1にはhidedenでログインするけど、その後はrootとして行動する????
(add-to-list 'tramp-default-proxies-alist
             '("gw1" "\\`root\\'" "/ssh:hideden@gw1:"))

想定した通りに動くんだけど、なんかOptionの解釈が間違ってるような。。ちゃんとマニュアル読めって事かな。。

あと、リモートホストzshでtrampがうまくプロンプトを見つけられない場合は.zshrcに

case "${TERM}" in
dumb | emacs)
    PROMPT="%n@%~%(!.#.$)"
    RPROMPT=""
    unsetopt zle
    ;;
esac

とか書いておけばうまくいった。zshのline editorが色々邪魔してるらしく、unsetopt zleが大事らしい。


(090111追記)
trump -> trampだった。。直しました。