andLinuxからWindowsコマンドの呼び出し

http://d.hatena.ne.jp/Nos/20081214/1229261624の続き。
andLinuxからWindowsに入ってるコマンド(TeXとか)を呼び出せるようにしてみる。Windowsに入っているものをLinuxの方にも入れちゃうのもなんだかもったいないし。


下準備としてちょっと小細工。
http://homepage1.nifty.com/emk/symlink.htmlあたりのジャンクション作成ソフトを使って

ln.exe -j C:\ C:\cygdrive\c
ln.exe -j D:\ C:\cygdrive\d
ln.exe -j E:\ C:\cygdrive\e

という感じでジャンクションを作る。

で、
andLinuxフォルダのsetting.txtの

cofs0=なんとか

のところを

cofs0=C:\cygdrive
cofs1=C:\docs

に変更(うちはc:\docsにものを置いてるのでそうでない人はcofs1の行は無視するなりしてください。後でdocs以下だけroot権限なしで書き込み可能にする目的で分けてある。)。
andlinuxの/etc/fstabの

/dev/cofs0 /mnt/win cofs defaults 0 0

のところを

cofs0 /cygdrive cofs defaults 0 0
cofs1 /mnt/docs cofs defaults,uid=ユーザー名 0 0

にする(/dev/cofs0でなくcofs0なのに注意)。

$ sudo mkdir /cygdrive /mnt/docs
$ ln -s /mnt/docs ~/docs

としてからandLinuxを再起動する。

windowsでサーバとしてrubyスクリプトを走らせたいのでcygwinを入れる。入れ方は割愛。
セットアップ過程でrubyをインストールしておく。
Windows側に
winexec-executer.rb:

#!/usr/bin/ruby
require 'drb/drb'
require 'open3'

DRb.start_service('druby://192.168.11.1:12346', Open3)
sleep

を置いて起動しておく(Windowsのデスクトップ上などで右クリックしてc:\cygwin\bin\ruby.exeを指定、できたショートカットを右クリック→プロパティからリンク先をC:\cygwin\bin\ruby.exe C:\scripts\winexec-executer.rbと変更しておいてそれを実行すれば楽かも?スタートアップにでも放り込んでおく。)。ちなみにポート番号の12346に特に意味はない。何かとかぶるようなら下のwinexec-teller.rbと合わせて変更する。
andLinux側に
winexec(/usr/local/binあたりに入れておく):

#!/bin/sh
PWD=$(/bin/pwd) || exit 1
CALLER=/scripts/winexec-teller.rb
if echo "$PWD" | grep '^/cygdrive' > /dev/null 2>&1; then
    exec "$CALLER" "$PWD" "$@"
elif echo "$PWD" | grep '^/mnt/docs' > /dev/null 2>&1; then
    PWD=$(echo "$PWD" | sed -e 's/\/mnt\/docs/\/cygdrive\/c\/docs/') || exit 1
    exec "$CALLER" "$PWD" "$@"
else
    echo "$(pwd): cannot map to Windows directory"
fi

とwinexec-teller.rb(流儀がよくわからないので/scriptsってディレクトリを作ってその下に置いておいた):

#!/usr/bin/ruby
require 'drb/drb'
DRbObject.new_with_uri("druby://windows-host:12346").call(ARGV)

を置く。で

$ sudo chmod 777 /usr/local/bin/winexec /scripts/winexec-teller.rb

として実行可能にする。
この時点で

$ cd /cygdrive/c/
$ winexec notepad test.txt

とかするとメモ帳が立ち上がるはず。
YaTeXを入れた状態なら.emacs

(setq tex-command "winexec platex")
(setq dvi2-command "winexec /cygdrive/c/usr/local/dviout/dviout")

と書いておけばok。
ただ標準入力をどうやってdrbの向こう側のプロセスに渡せばいいか分からなかったので対話機能が全く使えない*1。しかもdirのようなあっという間に終わるプログラムでもruby側で入力待機に入ってしまってどうもきれいでない。うまい方法はないかなあ。

参考:
http://www.am.ics.keio.ac.jp/members/iwaoka/wiki/index.php?coLinux
http://d.hatena.ne.jp/Trapezoid/20061129

*1:まあplatexに限っては対話がなくてもエラーがどこで発生したかは(最初のは)表示されるわけだからあまり問題ないんだけど