简体   繁体   English

使用ProcessBuilder在.java文件中运行shell命令

[英]Running shell commands within .java file using ProcessBuilder

I'm running into a pesky little error and I'm not sure how to solve it. 我遇到了一个讨厌的小错误,不确定如何解决。 What I'm trying to do is pretty simple: Run an external .java file using ProcessBuilder. 我想做的事情很简单:使用ProcessBuilder运行一个外部.java文件。 Just like that tittle suggests. 就像那个标题所暗示的那样。

The problem is that the file that runs and creates this ProcessBuilder is in a different directory than the other file I want to run. 问题在于,运行和创建此ProcessBuilder的文件与我要运行的另一个文件位于不同的目录中。

What I'm trying to do to get around this is: 为了解决这个问题,我想做的是:

String command[] = {"javac",JAVA_FILE_LOCATION};
ProcessBuilder processBuilder = new ProcessBuilder("cd");
Process process0 = processBuilder.start();

to reset the directory and 重置目录并

processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();

to compile the other file 编译另一个文件

if( process.getErrorStream().read() != -1 ){
    print("Compilation Errors",process.getErrorStream());
}

and just some error handling here. 以及这里的一些错误处理。 However it doesn't get past this error handle part. 但是,它并没有超过此错误处理部分。 I can't figure out the proper way of doing this. 我不知道这样做的正确方法。 Here's the error message: 这是错误消息:

my_PC:Processes user$ java -jar process.jar
************* Compilation Errors***********************
avac: file not found: /Users/Desktop/Piano.java
Usage: javac <options> <source files>
use -help for a list of possible options
Exception in thread "main" java.lang.IllegalThreadStateException: process hasn't exited
at java.lang.UNIXProcess.exitValue(UNIXProcess.java:423)
at my.package.address.Main.main(Main.java:28)

Does anyone know what I'm doing wrong ? 有人知道我在做什么错吗? Also I can post the whole code if needed, but I figured it's not really relevant here. 另外,如果需要的话,我可以发布整个代码,但是我发现这里并没有太大的意义。

UPDATED: added my code 更新:添加了我的代码

package some.random.package;

import java.io.*;

public class Main {
/**
* Provide absolute JAVA file path
*/
private static final String JAVA_FILE_LOCATION = "/Users/Desktop/piano.java";

    public static void main(String args[]) throws IOException
    {
        String command[] = {"javac",JAVA_FILE_LOCATION};
        ProcessBuilder processBuilder = new ProcessBuilder(command).directory(new File("/Users/Desktop/"));
        Process process = processBuilder.start();
        if( process.getErrorStream().read() != -1 ){
            print("Compilation Errors",process.getErrorStream());
        }
        /**
        * check if compile is successful
        * 0 => successful
        */
        if( process.exitValue() == 0 )
        {
            process = new ProcessBuilder(new String[]{"java","piano"}).directory(new File("/Users/Desktop/")).start();
            if( process.getErrorStream().read() != -1 )
                print("Errors ",process.getErrorStream());
            else
                print("Output ",process.getInputStream());

            /**
            * Check if RuntimeException or Errors encounter during execution then print errors on console
            * Otherwise print Output
            */
        }
    }
    private static void print(String status,InputStream input) throws IOException
    {
        BufferedReader in = new BufferedReader(new InputStreamReader(input));
        System.out.println("************* "+status+"***********************");
        String line = null;
        while((line = in.readLine()) != null ){
        System.out.println(line);
      }
    in.close();
    }
}

The cd command you execute with the first ProcessBuilder affects only that child process , it does not change the working directory of the main executing program. 您使用第一个ProcessBuilder执行的cd命令仅影响该子进程 ,它不会更改主执行程序的工作目录。 When you run the second ProcessBuilder , it will have the working directory as the main program, completely unaffected by the cd executed by the previous ProcessBuilder . 当您运行第二个ProcessBuilder ,它将把工作目录作为主程序,而完全不受先前ProcessBuilder执行的cd影响。

To execute a program from a different directory, use the directory(...) method of ProcessBuilder : 要从其他目录执行程序,请使用ProcessBuilderdirectory(...)方法:

String command[] = {"javac", JAVA_FILE_LOCATION};
ProcessBuilder processBuilder = new ProcessBuilder(command).directory(new File("path/to/dir"));
Process process0 = processBuilder.start();

Btw, the path "/Users/Desktop/piano.java" looks very strange. 顺便说一句,路径“ /Users/Desktop/piano.java”看起来很奇怪。 The path to a user's desktop on a Mac is usually /Users/username/Desktop , so the path in your code implies that your username is "Desktop", which is very unusual. 在Mac上,用户桌面的路径通常是/Users/username/Desktop ,因此代码中的路径表示您的用户名是“ Desktop”,这是非常不寻常的。

And, to make it easier to work with the program, I suggest to put the base directory path ( /Users/username/Desktop ) in a variable, rather then hardcoding it at multiple places. 并且,为使使用该程序更容易,我建议将基本目录路径( /Users/username/Desktop )放在变量中,而不是在多个位置进行硬编码。 That way it will be easier to make changes, no need to edit at multiple places. 这样一来,更改变得更加容易,无需在多个位置进行编辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM