Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
171 views
in Technique[技术] by (71.8m points)

java - How do I Pipe process output to a file on Windows and JDK 6u45

I have the following windows batch file (run.bat):

@echo off
echo hello batch file to sysout

And the following java code, which runs the batch files and redirects output to a file:

public static void main(String[] args) throws IOException {
    System.out.println("Current java version is: " + System.getProperty("java.version"));

    ProcessBuilder pb =
            new ProcessBuilder("cmd.exe", "/c",
                    "run.bat"
                     ,">>", "stdout.txt","2>>", "stderr.txt"
                    );
    System.out.println("Command is: " + pb.command());

    Process proc = pb.start();

    InputStream in = proc.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));

    String line = null;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }

    int exitValue = proc.exitValue();
    System.out.println("Exit value: " + exitValue);
}

On JDKs up to and including JDK6u43 I get the following output:

Current java version is: 1.6.0_29
Command is: [cmd.exe, /c, run.bat, >>, stdout.txt, 2>>, stderr.txt]
Exit value: 0

and the script output is written to the file. As of JDK 6u45 and 7, I get the following output:

Current java version is: 1.6.0_45
Command is: [cmd.exe, /c, run.bat, >>, stdout.txt, 2>>, stderr.txt]
hello batch file to sysout
Exit value: 0

And nothing is written to the output file.

This may or may not be related to the changes made in Runtime.exec() , described at: http://www.oracle.com/technetwork/java/javase/6u45-relnotes-1932876.html

What is the correct way of starting a process on Windows with output redirected to files?

Note: In a real world scenario, the command to execute may include parameters with spaces, as in:

ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c",
"run.bat", "Some Input With Spaces", 
">>", "stdout.txt","2>>", "stderr.txt");
question from:https://stackoverflow.com/questions/65857107/trying-to-run-linux-command-in-android-studio-but-it-is-crashing

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Several suggestions here:

  • Does the input with the spaces need to be treated as single String (with spaces),or id it in actual several inputs? If the first Option is the case I would suggest to quote it for the windows runtime:

ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", 
"run.bat", ""Some Input With Spaces"", 
">>", "stdout.txt","2>>", "stderr.txt");
  • Instead of redirecting the input to stdout.txt and stderr.txt using the shell, why not do it using Java using getOutputStream() and getErrorStream()? Here is an example using Guava's IO package. Of course you may want to have those in separate threads, you need proper exception handling, etc.

InputStream stdout = new BufferedInputStream(proc.getInputStream());
FileOutputStream stdoutFile = new FileOutputStream("stdout.txt");
ByteStreams.copy(stdout, stdoutFile);

InputStream stderr = new BufferedInputStream(proc.getErrorStream());
FileOutputStream stderrFile = new FileOutputStream("stderr.txt");
ByteStreams.copy(stderr, stderrFile);

stdout.close();
stderr.close();
stdoutFile.close();
stderrFile.close();
  • Another option, why not create a run.bat wrapper that will make the redirections?

@echo off
cmd.exe /c run.bat "%1" >> "%2" 2>> "%3"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...