2010-11-18 5 views
0

サブプロセスとして対話モードでshを実行するJavaプログラムがあります。入力はSystem.inからコピーされ、出力はSystem.outにコピーされます。例えば、出力が間違った順序で表示されます。この対話型シェルのコマンドなどpwdを実行するときにすべてがそれを除いて正常に動作します:サブプロセスの出力が間違った順序で表示されるのはなぜですか?

$ pwd 
$ /home/viz/workspace 

代わり

$ pwd 
/home/viz/workspace 
$ 

違いであるという最初のケースでpwdの出力の前にプロンプ​​ト$が出力されます。

なぜそれが起こりますか、それを修正する方法はありますか?標準エラーと標準出力が非同期に読み出したデータを印刷する別のスレッドに行くので

import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

class StreamCopier implements Runnable { 
    private InputStream in; 
    private OutputStream out; 

    public StreamCopier(InputStream in, OutputStream out) { 
     this.in = in; 
     this.out = out; 
    } 

    public void run() { 
     try { 
      int n; 
      byte[] buffer = new byte[4096]; 
      while ((n = in.read(buffer)) != -1) { 
       out.write(buffer, 0, n); 
       out.flush(); 
      } 
      out.close(); 
     } 
     catch (IOException e) { 
      System.out.println(e); 
     } 
    } 
} 

public class Test { 
    public static void main(String[] args) 
      throws IOException, InterruptedException { 
     Process process = Runtime.getRuntime().exec("sh -i +m"); 
     Thread outThread = new Thread(new StreamCopier(
       process.getInputStream(), System.out)); 
     outThread.start(); 
     Thread errThread = new Thread(new StreamCopier(
       process.getErrorStream(), System.err)); 
     errThread.start(); 
     Thread inThread = new Thread(new StreamCopier(
       System.in, process.getOutputStream())); 
     inThread.start(); 
     process.waitFor(); 
     outThread.join(); 
     errThread.join(); 
     inThread.join(); 
    } 
} 
+0

あなたが別のシェルを実行した場合はどうなりますか? – dacwe

+0

@dacwe:これまでのところshの作業しかできませんでした。試してみたが、IOをやろうとすると止められた。おそらく他のオプションが必要になるでしょう( '+ m'は助けになりません)。 – vitaut

答えて

1

:ここ

はコードです。あなたが2>&1をリダイレクトするとうまくいくかもしれませんが、Runtime.exec( "ファイルが見つかりません - 2> & 1"となる可能性があります)と動作するかどうかわかりません。だから、shを呼び出し、その出力をリダイレクトするシェルスクリプトを作成し、Runtime.execを使用してそのスクリプトを呼び出すことができます。

#!/bin/sh 
sh -i +m 2>&1 

Runtime.exec("customsh"); 
+0

しかし、 '$'と '/ home/viz/workspace'の両方を標準出力に出力する必要がありますか? (そのため、そこにレースはありません。) – dacwe

+0

@dacweいいえコマンドラインの 'sh 1> temp.log'から' pwd'と打ってみてください。コマンドラインプロンプトが表示されますが、pwd出力​​は表示されず、 'temp.log'に移動します。 – khachik

+0

ニース!それでは、ちょっとした解決策があります! – dacwe

関連する問題