2009-04-09

TRAMP

OpenSolarisをインストールしているホストのファイルを、Windows上のGNU Emacsから編集したくなったので、TRAMPを使おうと思ったところ、勢い良く落とし穴に嵌った。二度三度と嵌りたくないので、記録。

SSH経由での接続を想定。以下注意点。

  • tramp-default-methodをsshxにする
  • OpenSolaris上で実行するシェルは、/bin/shではなくて/bin/bashにする

まず、前者。GNU EmacsのWindowsバイナリからsshコマンドを起動する場合、sshの-tオプションを使わないと、仮想端末が割り当てられないので、リモートホストのシェルのプロンプトが出力されない。TRAMPはリモートホストのシェルのプロンプトの出力を待つため、こうなると処理が永遠に先に進まない。tramp-default-methodをsshxにすることで、sshが-tオプション付きで呼ばれるようになるので、この問題を避けられる。例。

(setq tramp-default-method "sshx")

次に後者。OpenSolarisの/bin/shはksh93へのシンボリックリンクだが、ksh93を使った場合、TRAMPの送るコマンドでクラッシュする。原因は、ksh上でHISTFILE変数を変更しようとすると、segmentation faultが発生するため。正直、目を疑ったが、そういう理由らしい。自分でkshを実行して同じことをしても再現率100%なので間違いない。幸い、/bin/bashが最初からあるので、代わりにこれを使う。

(require 'tramp)

(defun set-tramp-login-args (method args)
  (setcdr (assq 'tramp-login-args
                (assoc method tramp-methods))
          `(,args)))

(defun set-tramp-remote-sh (method sh)
  (setcdr (assq 'tramp-remote-sh
                (assoc method tramp-methods))
          `(,sh)))

(set-tramp-login-args "sshx" '("-e" "none" "-t" "-t" "/bin/bash --posix"))
(set-tramp-remote-sh "sshx" "/bin/bash --posix")

こんな感じ。わざわざ関数を定義しているのは、フックを使ってサーバ毎に設定の切り替えをしたかったからなんだけど、TRAMPにはそういうフックが定義されていなかった。マジですか。

Emacs 23.1付属のTRAMPでは、内部構造が変わったため、ここに書いてある設定では正常に動作しない。ksh93も、HISTFILE変数を変更したときの不具合が修正されたものを、Korn Shell 93 integration/migration projectでダウンロードできる。不具合が修正されたのが2009-06-16のリリースなので、それ以降のリリースでは問題ない。

0 件のコメント: