IT story

ProcessBuilder와 Runtime.exec ()의 차이점

hot-time 2020. 9. 5. 10:35
반응형

ProcessBuilder와 Runtime.exec ()의 차이점


Java 코드에서 외부 명령을 실행하려고하는데 Runtime.getRuntime().exec(...)사이에 차이점이 new Process(...).start()있습니다.

사용시 Runtime:

Process p = Runtime.getRuntime().exec(installation_path + 
                                       uninstall_path + 
                                       uninstall_command + 
                                       uninstall_arguments);
p.waitFor();

exitValue는 0이고 명령은 정상적으로 종료됩니다.

그러나 ProcessBuilder:

Process p = (new ProcessBuilder(installation_path +    
                                 uninstall_path +
                                 uninstall_command,
                                 uninstall_arguments)).start();
p.waitFor();

종료 값은 1001이고 명령 waitFor은 반환 되지만 중간에서 종료됩니다 .

문제를 해결하려면 어떻게해야 ProcessBuilder합니까?


의 다양한 오버로드는 Runtime.getRuntime().exec(...)문자열 배열 또는 단일 문자열을 사용합니다. 의 단일 문자열 오버로드 exec()는 문자열 배열을 사용하는 exec()오버로드 중 하나에 문자열 배열을 전달하기 전에 문자열을 인수 배열로 토큰 화합니다 . 반면 ProcessBuilder생성자는 문자열의 varargs 배열 또는 문자열의 a 만 취하며 List배열 또는 목록의 각 문자열은 개별 인수로 간주됩니다. 어느 쪽이든, 얻은 인수는 실행을 위해 OS에 전달되는 문자열로 결합됩니다.

예를 들어 Windows에서는

Runtime.getRuntime().exec("C:\DoStuff.exe -arg1 -arg2");

DoStuff.exe주어진 두 개의 인수 프로그램을 실행합니다 . 이 경우 명령 줄이 토큰 화되고 다시 합쳐집니다. 하나,

ProcessBuilder b = new ProcessBuilder("C:\DoStuff.exe -arg1 -arg2");

이름이있는 프로그램이있을 발생하지 않는 한, 실패 DoStuff.exe -arg1 -arg2에를 C:\. 이는 토큰 화가 없기 때문입니다. 실행할 명령이 이미 토큰 화되었다고 가정합니다. 대신

ProcessBuilder b = new ProcessBuilder("C:\DoStuff.exe", "-arg1", "-arg2");

또는 대안으로

List<String> params = java.util.Arrays.asList("C:\DoStuff.exe", "-arg1", "-arg2");
ProcessBuilder b = new ProcessBuilder(params);

어떻게 봐 Runtime.getRuntime().exec()받는 문자열 명령을 전달합니다 ProcessBuilder. 그러므로, 호출하는 토크 나이저를 사용하여 개별 토큰으로 명령을 폭발 exec(String[] cmdarray, ......)를 구성한다 ProcessBuilder.

당신이를 구성하는 경우 ProcessBuilder대신 하나 하나의 문자열 배열로, 같은 결과를 얻을 수 있습니다.

ProcessBuilder생성자는 필요 String...하나의 문자열로 전체 명령을 전달하는 터미널에서 따옴표로 그 명령을 호출하는 것과 같은 효과가 있으므로, 가변 인자를 :

shell$ "command with args"

네, 차이가 있습니다.

  • Runtime.exec(String)메서드 는 명령과 일련의 인수로 분할되는 단일 명령 문자열을 사용합니다.

  • ProcessBuilder생성자 문자열 (변수 인수) 배열 걸린다. 첫 번째 문자열은 명령 이름이고 나머지는 인수입니다.

그래서 당신이 ProcessBuilder에게 명령하는 것은 이름에 공백과 다른 쓰레기가있는 "명령"을 실행하는 것입니다. 물론 운영 체제는 해당 이름의 명령을 찾을 수 없으며 명령 실행이 실패합니다.


구현 은 다음 ProcessBuilder.start()Runtime.exec()같기 때문에 차이가 없습니다 Runtime.exec().

public Process exec(String command) throws IOException {
    return exec(command, null, null);
}

public Process exec(String command, String[] envp, File dir)
    throws IOException {
    if (command.length() == 0)
        throw new IllegalArgumentException("Empty command");

    StringTokenizer st = new StringTokenizer(command);
    String[] cmdarray = new String[st.countTokens()];
    for (int i = 0; st.hasMoreTokens(); i++)
        cmdarray[i] = st.nextToken();
    return exec(cmdarray, envp, dir);
}

public Process exec(String[] cmdarray, String[] envp, File dir)
    throws IOException {
    return new ProcessBuilder(cmdarray)
        .environment(envp)
        .directory(dir)
        .start();
}

그래서 코드 :

List<String> list = new ArrayList<>();
new StringTokenizer(command)
.asIterator()
.forEachRemaining(str -> list.add((String) str));
new ProcessBuilder(String[])list.toArray())
            .environment(envp)
            .directory(dir)
            .start();

다음과 같아야합니다.

Runtime.exec(command)

의견을 보내 주셔서 감사합니다 dave_thompson_085

참고URL : https://stackoverflow.com/questions/6856028/difference-between-processbuilder-and-runtime-exec

반응형