Java では、UNIX/C のプログラムを、ある意味では特徴付ける、
fork() , exec() , wait() ... といった、プロセスを生成し、プログラムを実行する
働きをもった一群の関数群を、ほとんど用いません。
なぜなら、Java では、cpuにとって重たい処理であるforkに代わって、軽いThreadが、
言語仕様そのものに組み込まれる形で、全面的に使われるからです。
appletの中では、セキュリティの関係で、自由に他のプログラムを実行することは、
許されません。所が、Javaアプリケーションでは、こうしたことが可能になります。
ただ、この時、他のプログラムは、Thread ではなく、forkで生成されたサブ・プロセス
の中で、実行されることになります。今回は、forkで生成されたサブ・プロセス
からの入出力をどう扱うかという問題を取り扱ってみましょう。
次のプログラムは、引数に与えたプログラムを実行してその出力を表示するものです。 簡単な実行例を示します。
sparc04$ java Exec who <---- who コマンドを実行 pid 5357 status 0 Received sigchild for 5357 exit=0 nakaga-h pts/0 6月 25 19:08 (lxb4) maruyama pts/2 6月 25 20:35 (ews1) sparc04$ java Exec ls -l *.txt <---- ls -l *.txt を実行 pid 5328 status 0 Received sigchild for 5328 exit=0 -rw-r--r-- 1 maruyama sysadmin 16681 6月 24日 23:46 sw4.txt sparc04$ java Exec ypcat hosts | grep cronos <---- ホストcronos の検索 202.11.101.9 cronos
このサンプルの中心部分は、次の行です。
proc = Runtime.getRuntime().exec(cmd);
ただ、この行のことは、ドキュメントを見て考えればわかります。
実際には、このサンプルで一番苦労したのは、次の2点です。
第一。サブ・プロセスとJavaとの同期がうまく取れません。 そのために、available()というメソッドを使っています。Streamに データが無いときには、sleepで、ちょっと待つことにしています。 第二。先の行で生成されたprocessオブジェクトから、getInputStream()を 使って、InputStreamを獲得するのですが、InputStreamのままでは、 サブ・プロセスの終了が感知できません
in = new DataInputStream(proc.getInputStream());
というように、DataInputStreamにすると、なぜかわかりませんが、
この問題は解決します。
**************************** ** Exec.java **************************** 1 import java.lang.* ; 2 import java.io.* ; 3 4 class Exec { 5 Process proc = null ; 6 DataInputStream in = null; 7 8 Exec( String arg[] ){ 9 try{ 10 String cmd[] = new String[3] ; 11 StringBuffer args = new StringBuffer(); 12 13 if (arg.length == 0) return ; 14 for (int i = 0; i < arg.length; i++) { 15 args.append(' ').append(arg[i]); 16 } 17 cmd[0] = "/usr/bin/ksh"; 18 cmd[1] = "-c"; 19 cmd[2] = args.toString(); 20 21 proc = Runtime.getRuntime().exec(cmd); 22 in = new DataInputStream(proc.getInputStream()); 23 24 } catch ( Exception ex){ 25 System.err.println("exec: "+ex); 26 } 27 } 28 29 public static void main(String argv[]){ 30 try { 31 Exec d = new Exec(argv); 32 String line = null ; 33 34 int size = 0 ; 35 while( true ){ 36 if ( d.in.available() > 0 ){ 37 while( (line = d.in.readLine()) != null ){ 38 System.out.println(line); 39 } 40 break ; 41 } else { 42 Thread.sleep(200); 43 } 44 45 } 46 } catch ( Exception ex){ 47 System.err.println("main:"+ex); 48 } 49 } 50 }