対話型プログラムを透過的に使う
gdb や js や irb などのプログラムは、ユーザーとの持続的な対話を想定したインターフェースになっていますが、その対話型インターフェースを裏に隠してしまって、いつでも端末から透過的に対話を実行できれば何かとうれしそうです(こういうツールありそうだけど、意外と見つらない)。
具体例を示します。
% js js> function hello() { print("Hello!") } js> hello() Hello! js> ^D // ここで端末でコマンドを実行したくなったので ^D で終了 % # 何かやる % js js> hello() // 一回終了したので未定義 typein:1: ReferenceError: hello is not defined
上記のように、従来のインターフェースでは端末と対話型プログラムを同時に使うことができません。これを以下のように同時に使えるようにしたいわけです。
% jsdo 'function hello() { print("Hello!") }; hello()' Hello! % # 何かやる % jsdo 'hello()' Hello!
実装の話
UNIX ドメインソケットを使ってクライアント/サーバー形式で実装します。クライアントはサーバーに実行したいコマンドを送信し、その結果を受信して標準出力に出力します。サーバーはクライアントから受けとったコマンドを受信し、 expect に渡してその結果を待ちます。結果が得られたらクライアントに返信します。サーバーによって popen されている expect は対話型プログラムを spawn してプロンプトの監視を行います。プロンプトが出てきた時点でサーバーに結果を返すようになっています。
イントール
まず ruby と expect がインストールされていることを確認してください。
% ruby --version ruby 1.8.6 (2007-09-24 patchlevel 111) [x86_64-linux] % expect -v expect version 5.42.1
次に本体の Ruby スクリプトをインストールします。
% cd ~/bin % wget http://shdo.googlecode.com/svn/trunk/shdo % chmox +x shdo % type shdo shdo is /home/tomo/bin/shdo
使い方
shdo start <name> <command> の形式で対話型プログラムを実行しておき、 shdo execute <name> <command> の形式でコマンドを実行します。
js なら以下のようにします。
% shdo start myjs js % shdo execute myjs 'print("Hello")' Hello
プロンプトを認識するための正規表現はデフォルトでは \w*>\s*$ です。 irb などの場合は以下のようにする必要があります。
% shdo start --prompt '>> $' myirb irb --simple-prompt % shdo execute myirb 'puts "Hello"' Hello => nil
出力をパイプしたりできるのでいろいろな使いかたが考えられます。
ちなみに shdo ls で起動しているプログラムを一覧できます(まだ未実装)。
% shdo ls myjs /tmp/shdo-js myirb /tmp/shdo-myirb
ラッパーを作る
いちいち shdo start とか shdo execute していては面倒なので以下のようなラッパーを書くようにしましょう。
~/bin/jsdo:
#!/bin/sh name=jsdo if ! shdo ls $name > /dev/null; then shdo start --prompt 'js> $' $name js fi exec shdo execute $name $@
以下のように使います。
% jsdo function adder(a) { return function(b) { return a + b } } % jsdo 'adder(1)(2)' 3
問題点
対話型プログラム内でユーザーに入力を要求する処理が実行されると止まります。
% shdo start --prompt 'SQL> $' mysqlplus sqlplus /nolog % shdo execute mysqlplus 'conn scott' 止まる
この辺りは徐々に改善します。
何に使うの
次に書くエントリの布石として、このツールを作ったのですが、それ以外で用途があるかと言われると正直答えられません。誰か面白い使い方を発明してください。
- Category(s)
- linux
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/use-interactive-program-trasparently/tbping