0


スクリプトを実行するために Apache コモンズを使用しようとしていますが、端末から実行されたスクリプトは次のようなデータを出力するように見えます

$./old-regress.sh


End with '*' as postcode !

            postcode:                 city:               street:         house number:              country:                 name:                  PDC: 
postcode           :      
city               : 
street             : 
house_num          : 
routing_code       : 
post_freight_centre: 
ic_c_err_code      : 0260
post_code_err_code : ----
city_error_code    : g---
street_error_code  : ---f
local_gov_number 1 : 
local_gov_number 2 : 
State              : 
admin. district    : 
district           : 
local gov. unit    : 
routing_code       : 
error_text_address : 
./old-regress.sh: line 2:  9722 Segmentation fault      ./ictest < /tmp/tmp_inp_file

セグメンテーション違反は、バイナリictest(サード パーティ) がどのように機能するかによって予想されます。

Apache Commons execを使用してアプリから同じスクリプトを実行しようとすると、出力ではなくエラーのみが出力されるようです。スクリプトを実行しようとする私のコード スニペットは次のとおりです -

public class Test {
public String execToString(String command) throws Exception {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    CommandLine commandline = CommandLine.parse(command);
    DefaultExecutor exec = new DefaultExecutor();
    exec.setWorkingDirectory(new File("/home/vigna"));
    PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
    exec.setStreamHandler(streamHandler);
    exec.setExitValue(139);
    DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
    exec.execute(commandline,resultHandler);
    resultHandler.waitFor();
    return(outputStream.toString());
}
public static void main(String[] argv) throws Exception {
    Test test = new Test();
    System.out.println(test.execToString("./old-regress.sh"));
}

上記のスニペットが返す出力は次のとおりです --

./old-regress.sh: line 2: 15981 Segmentation fault      ./ictest < /tmp/tmp_inp_file

編集 2 -- ProcessBuilder を使用してみました。以下は私のコードです-

public class PBTest
{
    public static void main(String[] args) throws Exception
    {
        ProcessBuilder pb = new ProcessBuilder("./old-regress.sh");
        pb.directory(new File("/home/xxx/"));
        Process p = pb.start();
        String output = loadStream(p.getInputStream());
        String error  = loadStream(p.getErrorStream());
        int rc = p.waitFor();
        System.out.println("Process ended with rc=" + rc);
        System.out.println("\nStandard Output:\n");
        System.out.println(output);
        System.out.println("\nStandard Error:\n");
        System.out.println(error);
    }
    private static String loadStream(InputStream s) throws Exception
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(s));
        StringBuilder sb = new StringBuilder();
        String line;
        while((line=br.readLine()) != null)
            sb.append(line).append("\n");
        return sb.toString();
    }
}

ProcessBuilder を使用した結果は次のとおりです --

Process ended with rc=139
Standard Output:


Standard Error:

./old-regress.sh: line 2:  3975 Segmentation fault      ./ictest < /tmp/tmp_inp_file

139 はセグメンテーション違反が原因であり、失敗の原因になっている可能性があると考えています。何か提案はありますか?

ここで何が間違っているのかについての指針はありますか?出力もキャプチャするにはどうすればよいですか?

4

2 に答える 2

1

org.apache.commons.exec.LogOutputStreamByteArrayOutputStream の代わりに使用することをお勧めします。単一引数の PumpStreamHandler コンストラクターは stdout と stderr をキャプチャします。LogOutputStream のインスタンスを作成し、単一の引数として PumpStreamHandler に渡します (BAOS のように)。

Handler で waitFor() を呼び出すだけなので、 DefaultExecutor: で同期実行メソッドを使用するだけですint exitValue = exec.execute(commandline)

終了コードを null に設定してから、execute からの応答から自分で exitValue を確認します。問題は、ByteArrayOutputStream が例外から切り捨てられ、stdout を打ち負かし、コンテンツを完全にフラッシュしていないことだと思います。

于 2012-11-26T20:05:47.173 に答える
0

あなたがやっている。

exec.execute(commandline);
// gives the program no time to start or run.
return(outputStream.toString());

代わりに次のようなことをする必要があります

exec.execute(commandline).waitFor();    
// get the output only after the program has finished.
return(outputStream.toString());
于 2012-11-19T11:31:15.273 に答える