MeadowからcoLinuxのシェルを叩く
状況設定
なにかと制限されがちなcygwinから解放されるべく、Meadowからのものも含めたすべてのコマンド実行をcoLinux内で行いつつ、ファイルの受け渡しはシームレスに行えるようにする。
以下の設定はcoLinuxのような(ファイアウォールの必要もないような)閉じた環境のためのものなので、外からアクセスできるようなホストに使っては決していけません。
手順
- coLinuxを用意する。
- sshは公開鍵を設定してパスワード入力無しで入れるようにしておく。
- smbfsでマウント先にIPアドレスを指定するのは良くないらしいので/etc/hostsに親のアドレスを書いておく。
# /etc/hosts 192.168.153.2 coa 192.168.153.1 fate
- sambaを入れて、coa側の/をネットワークドライブ(s:)にマウントしておく。パスワード無しでアクセスできるようにするには以下のようにsmb.confに書いておく。
# /etc/samba/smb.conf [global] # ... snip ... security = share guest account = nya # ... snip ... [coa] path = / writable = yes public = yes only guest = yes browsable = yes
- 逆に、fateのドライブルートをsmbfsでマウントする。fstabに書くとifupdownとの順序の兼ね合いがあったりするのでrc.localに。/etc/secret/fate-passwdにはログイン情報を書いておく。
# /etc/rc.local mount -t smbfs -o codepage=cp932,iocharset=utf8,credentials=/etc/secret/fate-passwd,uid=nya,gid=nya,fmask=0700,dmask=0700 //fate/fate /fate
- fakecygptyをダウンロードしてコンパイル。f_ssh.exeとしてc:/cygwin/bin/に配置する。
- シェルコマンドの実行用スクリプトをc:/cygwin/bin/coainvokeに作成する。ここで-tオプションをつけないとちゃんとしたptyとならず(?)、すぐにリモートプロセスがゾンビ化するので注意。スクリプト内で、渡されたパス名の書き換えを行う。
#!/usr/bin/perl # coainvoke use strict; use Cwd; my $wd = Cwd::getcwd(); $wd =~ s#^/cygdrive/c/#/fate/#; $wd =~ s#^/cygdrive/s/#/#; my $cmd = join(' ', @ARGV); exec('f_ssh', '-t', 'coa', "cd \"$wd\"; $cmd");
#!/usr/bin/perl # coashell exec("f_ssh -t coa");
- Meadowのshellを変更。
; .emacs (setq shell-file-name "coainvoke") (setq explicit-shell-file-name "coashell") (setq shell-command-switch "") (setq explicit-coashell-args '())
; .emacs (defadvice shell-process-cd (before shell-process-cd-rewrite (arg) activate) "shell-process-cd-rewrite" (cond ((string-match "^/fate/" arg) (setq arg (replace-regexp-in-string "^/fate/" "c:/" arg))) ((string-match "^~" arg) (setq arg (replace-regexp-in-string "^~" "c:/home" arg))) ((string-match "^/" arg) (setq arg (concat "s:" arg)))))
(defadvice gdb-source (after gdb-source-rewrite activate) "gdb-source-rewrite" (setcar gud-last-frame (replace-regexp-in-string "^/fate/" "c:/" (car gud-last-frame))) )
- ついでにぼくの場合は自分で作って使っているelscreenの拡張にもパス名の書き換えを追加。
(defun elscreen-local-shell () "Open local shell with new screen." (interactive) (let* ((dir default-directory) (buffer (get-buffer-create "*shell*")) (screen (elscreen-find-screen-by-buffer buffer))) (setq dir (replace-regexp-in-string "^~" "/fate/home" dir)) (setq dir (replace-regexp-in-string "^c:/" "/fate/" dir)) (setq dir (replace-regexp-in-string "^s:/" "/" dir)) (if (null screen) (elscreen-create) (elscreen-goto screen)) (switch-to-buffer buffer) (shell) (let ((proc (get-buffer-process buffer))) (comint-send-string proc "echo \"cd ") (comint-send-string proc dir) (comint-send-string proc "\" ; cd \"") (comint-send-string proc dir) (comint-send-string proc "\"\n")))) (define-key elscreen-map "\C-s" 'elscreen-local-shell) (define-key elscreen-map "s" 'elscreen-local-shell)
こんなところで一通り使えるようになった。