Rubyを使って、シェルのコマンドを実行する必要があったのですが、ちょっと手間取ったので、それに関するメモ
普通にコマンドを実行
Rubyさんは便利なもんで、言語の規格としてコマンド実行の手段が用意されています。
`mkdir hogehoge`
このように書くとコマンドが実行できます。便利ですね。
ちなみにこの文の戻り値がコマンドの実行結果となっています。
puts `ls -la`
しかし、この手法にはちょっと問題があります。
コマンドを実行した後に標準入力を食わせる必要のあるコマンドを実行したいときに、標準入力を食わせることができません。あら残念
ということで、そのようなことをする必要がある際は、次の方法をとる必要があります
コマンドを実行後、標準入力を食わせる方法
「リダイレクションを使って、コマンドの入出力をストリームで開く」って感じなのかな?
result=open("| ftp ftp://user:pass@hogehoge","r+") result.puts("ls") result.puts("help") result.puts("exit") while l=result.gets puts l end
例だと、hogehogeにftp接続をして、lsとhelpを実行して結果を取得しています。
実行結果例はこんな感じ
% ruby kakisute.rb drw-rw-rw- 1 user group 0 Jun 20 08:55 FTPHome Commands may be abbreviated. Commands are: ! features mls prompt site $ fget mlsd proxy size account form mlst put sndbuf append ftp mode pwd status ascii gate modtime quit struct bell get more quote sunique binary glob mput rate system bye hash mreget rcvbuf tenex case help msend recv throttle cd idle newer reget trace cdup image nlist remopts type chmod lcd nmap rename umask close less ntrans reset unset cr lpage open restart usage debug lpwd page rhelp user delete ls passive rmdir verbose dir macdef pdir rstatus xferbuf disconnect mdelete pls runique ? edit mdir pmlsd send epsv4 mget preserve sendport exit mkdir progress set
しかしながら、これも色々と欠点があります。
同じストリームに対して、コマンドの出力を見ながら、コマンドを実行するなどということができません。
なので、得られた標準出力の結果から、何が実行されたかを類推する必要があります
result.putsの位置をgetsの後に持っていってもうまくいきません。何とも面倒な話です。
もしかしたら、リダイレクションで標準入力をファイルにつなげて、そのファイルをRubyから開いて書き込む。という方法をすればうまくいくかもしれません。試してないけど。
TetraMAXの-shellに特定の処理を食わせる
私がしたかったのはこれ。
まぁこんなことをしたい人が世の中にどれくらい居るかは知りませんが・・・
書き捨てコードだけど一応メモっておきます。
#! ruby -Ku class TMaxShellRun def initialize(obj=[]) @commandList=obj end #コマンドをAddする def add(value) @commandList.push(value) end def run i=0 strs=[] result=open("| tmax -shell","r+") for com in @commandList result.puts com end tempStr="" tempL=[] while l=result.gets if tempL.size!=0 && l.include?('-T>') tempL.push(tempStr) strs.push(tempL.clone) tempL=[@commandList[i]] l.match(/.+-T> *(.*)$/) tempStr=" " + $1 + "\n" i+=1 elsif tempL.size!=0 tempStr+=l elsif l.include?('-T>') tempL=[@commandList[i]] tempStr=l.sub(/.+-T>(.*)$/,"") i+=1 end end result.close @returnlist=strs end attr_accessor :returnlist end #ここからTMaxShellRunクラスの使い方 obj = TMaxShellRun.new obj.add('read_netlist class.v -library') obj.add('read_netlist netlist.v') obj.add('run_build_model netlist') obj.add('run_drc') obj.add('add_faults -all') obj.add('report_faults -all -collapsed') obj.add('exit') obj.run puts "#{obj.returnlist[-1][0]}の実行結果は" puts obj.returnlist[-1][1]
*1:どう考えてもこのコード汚い